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