В дополнение к другим хорошим ответам я добавлю еще одну причину, по которой не следует добавлять константу в стиле C в C #. Ты сказал:
мы помечаем параметр как const, чтобы быть уверенным, что его состояние не изменится в методе.
Если бы const действительно это сделала, было бы здорово. Конст этого не делает. Константа - это ложь!
Const не дает никаких гарантий, что я действительно могу его использовать. Предположим, у вас есть метод, который принимает константу. Есть два автора кода: человек, пишущий вызывающий, и человек, пишущий вызываемого . Автор вызываемого объекта заставил метод принимать константу. Что, по мнению двух авторов, является неизменным относительно объекта?
Ничего. Вызываемый может отбросить константу и изменить объект, поэтому вызывающий не имеет гарантии, что вызов метода, который принимает константу, на самом деле не изменит ее. Точно так же вызываемый объект не может предполагать, что содержимое объекта не будет изменяться на протяжении действия вызываемого объекта; вызываемый может вызвать какой-либо изменяющий метод для псевдонима, отличного от const, для объекта const, и теперь так называемый объект const изменился .
Константа в стиле C не гарантирует, что объект не изменится и, следовательно, сломан. Теперь у C уже есть слабая система типов, в которой вы можете переинтерпретировать приведение двойника к int, если вы действительно этого хотите, поэтому неудивительно, что он также имеет слабую систему типов по отношению к const. Но C # был разработан, чтобы иметь хорошую систему типов, систему типов, в которой, когда вы говорите «эта переменная содержит строку», переменная фактически содержит ссылку на строку (или null). Мы абсолютно не хотим добавлять модификатор "const" в стиле C в систему типов, потому что мы не хотим, чтобы система типов была ложью . Мы хотим, чтобы система типов была сильной, чтобы вы могли правильно рассуждать о своем коде.
Const в C - это руководство ; в основном это означает: «Вы можете поверить, что я не буду пытаться видоизменить эту вещь». Этого не должно быть в системе типов ; материал в системе типов должен быть фактом об объекте, о котором вы можете рассуждать, а не руководством к его использованию.
Не поймите меня неправильно; просто потому, что const в C глубоко сломан, не означает, что вся концепция бесполезна. Я бы хотел увидеть действительно правильные и полезные форму аннотации «const» в C #, аннотацию, которую люди и компиляторы могут использовать, чтобы помочь им понять код, и которую среда выполнения могла бы использовать для таких вещей, как автоматическая параллелизация и другие расширенные оптимизации.
Например, представьте, что вы можете «нарисовать рамку» вокруг фрагмента кода и сказать: «Я гарантирую, что этот фрагмент кода не выполняет никаких изменений ни в одном поле этого класса» таким образом, чтобы это могло быть проверено компилятором. Или нарисуйте рамку с надписью «этот чистый метод изменяет внутреннее состояние объекта, но никак не наблюдаемым за пределами рамки». Такой объект не может быть безопасно многопоточным автоматически, но он может быть автоматически мемоизирован . Есть всевозможные интересные аннотации, которые мы могли бы добавить в код, которые позволят провести обширную оптимизацию и более глубокое понимание. Мы можем добиться большего, чем слабая аннотация const в стиле C.
Однако подчеркиваю, что это всего лишь домыслы . У нас нет твердых планов по включению такой функции в какую-либо гипотетическую будущую версию C #, если она вообще есть, о которой мы так или иначе не объявили. Это то, что я хотел бы увидеть, и то, что может потребоваться в связи с предстоящим акцентом на многоядерные вычисления, но ничто из этого никоим образом не должно толковаться как предсказание или гарантия какой-либо конкретной функции или будущего направления для C #.
Теперь, если то, что вы хотите, - это просто аннотация к локальной переменной, которая является параметром, который говорит, что «значение этого параметра не изменяется на протяжении всего метода», тогда, конечно, это будет легко сделать. Мы могли бы поддерживать локальные переменные и параметры «только для чтения», которые инициализировались бы один раз, а также ошибку времени компиляции для изменения в методе. Переменная, объявленная оператором using, уже является такой локальной; мы могли бы добавить необязательную аннотацию ко всем локальным переменным и параметрам, чтобы они действовали как «использующие» переменные. Это никогда не было функцией с очень высоким приоритетом, поэтому она никогда не была реализована.