Além de outras boas respostas, acrescentarei outra razão para não colocar constância do estilo C no C #. Você disse:
marcamos o parâmetro como const para ter certeza de que seu estado não será alterado no método.
Se const realmente fizesse isso, seria ótimo. Const não faz isso. O const é uma mentira!
Const não oferece nenhuma garantia de que eu possa realmente usar. Suponha que você tenha um método que usa uma coisa const. Existem dois autores de código: a pessoa que escreve o chamador e a pessoa que escreve o receptor . O autor do chamado fez com que o método assumisse uma const. O que os dois autores podem assumir é invariável em relação ao objeto?
Nada. O callee está livre para rejeitar const e transformar o objeto, portanto, o chamador não tem garantia de que chamar um método que usa const realmente não o fará sofrer mutação. Da mesma forma, o receptor não pode assumir que o conteúdo do objeto não mudará durante a ação do receptor; o callee pode chamar algum método mutante em um alias não const do objeto const, e agora o chamado objeto const mudou .
Const de estilo C não fornece garantia de que o objeto não será alterado e, portanto, está quebrado. Agora, C já tem um sistema de tipo fraco no qual você pode fazer uma reinterpretação de um duplo em um int se realmente quiser, então não deve ser uma surpresa que ele tenha um sistema de tipo fraco com respeito a const também. Mas C # foi projetado para ter um bom sistema de tipos, um sistema de tipos onde, quando você diz "esta variável contém uma string", a variável realmente contém uma referência a uma string (ou nula). Não queremos absolutamente colocar um modificador "const" no estilo C no sistema de tipos porque não queremos que o sistema de tipos seja uma mentira . Queremos que o sistema de tipos seja forte para que você possa raciocinar corretamente sobre o seu código.
Const em C é uma diretriz ; basicamente significa "você pode confiar em mim para não tentar transformar essa coisa". Isso não deveria estar no sistema de tipos ; as coisas no sistema de tipos devem ser um fato sobre o objeto sobre o qual você pode raciocinar, não uma diretriz para seu uso.
Agora, não me entenda mal; só porque const em C está profundamente quebrado não significa que todo o conceito seja inútil. O que eu adoraria ver é alguma forma realmente correta e útil de anotação "const" em C #, uma anotação que humanos e compiladores podem usar para ajudá-los a entender o código, e que o tempo de execução pode usar para fazer coisas como paralelização automática e outras otimizações avançadas.
Por exemplo, imagine se você pudesse "desenhar uma caixa" em torno de um pedaço de código e dizer " Garanto que esse pedaço de código não executa mutações em nenhum campo desta classe" de uma forma que pudesse ser verificada pelo compilador. Ou desenhe uma caixa que diga "este método puro altera o estado interno do objeto, mas não de qualquer maneira que seja observável fora da caixa". Esse objeto não poderia ser multithread automaticamente com segurança, mas poderia ser memoized automaticamente . Existem todos os tipos de anotações interessantes que poderíamos colocar no código que permitiriam otimizações ricas e um entendimento mais profundo. Podemos fazer muito melhor do que a fraca anotação const do estilo C.
No entanto, enfatizo que isso é apenas especulação . Não temos planos firmes de colocar esse tipo de recurso em qualquer versão futura hipotética do C #, se é que existe uma, que não anunciamos de uma forma ou de outra. É algo que eu adoraria ver e algo que a próxima ênfase na computação de vários núcleos pode exigir, mas nada disso deve ser interpretado de forma alguma como uma previsão ou uma garantia de qualquer recurso particular ou direção futura para C #.
Agora, se o que você deseja é apenas uma anotação na variável local que é um parâmetro que diz "o valor deste parâmetro não muda ao longo do método", então, claro, isso seria feito facilmente. Poderíamos suportar locais e parâmetros "somente leitura" que seriam inicializados uma vez e um erro em tempo de compilação para alterar o método. A variável declarada pela instrução "using" já é um local; poderíamos adicionar uma anotação opcional a todos os locais e parâmetros para fazê-los agir como variáveis "usando". Nunca foi um recurso de prioridade muito alta, então nunca foi implementado.