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