Почему параметры константы не позволяются в C#?

Это выглядит странным специально для разработчиков C++. В C++ мы раньше отмечали параметр как const чтобы быть уверенным, что его состояние не будет изменено в методе. Существует также другой C++ определенные причины, как передача const ref чтобы пройти мимо касательно и быть уверенным, что состояние не будет изменено. Но почему мы не можем отметить как константу параметров метода в C#?

Почему я не могу объявить свой метод как следующее?

    ....
    static void TestMethod1(const MyClass val)
    {}
    ....
    static void TestMethod2(const int val)
    {}
    ....
98
задан Peter Mortensen 15 January 2017 в 12:35
поделиться

4 ответа

В дополнение к другим хорошим ответам, я добавлю еще одну причину, почему не стоит вводить в C# константность в стиле C. Вы сказали:

мы помечаем параметр как const, чтобы быть уверенными, что его состояние не будет изменено в методе.

Если бы const действительно это делала, это было бы замечательно. Const этого не делает. const - это ложь!

Const не дает никакой гарантии, которую я мог бы реально использовать. Предположим, у вас есть метод, который принимает const. Есть два автора кода: человек, пишущий caller, и человек, пишущий callee. Автор вызывающей стороны сделал метод принимающим const. Что оба автора могут предположить неизменным в объекте?

Ничего. Вызывающий может отбросить const и изменить объект, поэтому у вызывающего нет гарантии, что вызов метода, принимающего const, не приведет к его изменению. Аналогично, вызывающий не может предположить, что содержимое объекта не изменится во время действий вызывающего; вызывающий может вызвать какой-нибудь мутирующий метод на не const псевдониме объекта const, и теперь так называемый объект const изменился.

const в стиле C не дает гарантии, что объект не изменится, и поэтому является нерабочим. Итак, в C уже есть слабая система типов, в которой вы можете сделать переинтерпретацию двойки в int, если очень захотите, поэтому не стоит удивляться, что в нем есть слабая система типов и в отношении const. Но C# был разработан, чтобы иметь хорошую систему типов, систему типов, в которой, когда вы говорите "эта переменная содержит строку", переменная действительно содержит ссылку на строку (или null). Мы совершенно не хотим вводить в систему типов модификатор "const" в стиле C, потому что мы не хотим, чтобы система типов была ложью. Мы хотим, чтобы система типов была сильной, чтобы вы могли правильно рассуждать о своем коде.

Const в C - это руководство; в основном это означает "вы можете доверять мне, что я не буду пытаться мутировать эту вещь". Этого не должно быть в системе типов; вещи в системе типов должны быть фактом об объекте, о котором вы можете рассуждать, а не руководством по его использованию.

Не поймите меня неправильно; то, что const в C глубоко сломана, не означает, что вся концепция бесполезна. Я бы хотел увидеть в C# некую правильную и полезную форму аннотации "const", аннотацию, которую и люди, и компиляторы могли бы использовать для понимания кода, и которую среда выполнения могла бы использовать для таких вещей, как автоматическая паралеллизация и другие продвинутые оптимизации.

Например, представьте, если бы вы могли "нарисовать рамку" вокруг куска кода и сказать: "Я гарантирую, что этот кусок кода не выполняет никаких мутаций ни с одним полем этого класса" таким образом, чтобы компилятор мог это проверить. Или нарисуйте рамку с надписью "этот чистый метод изменяет внутреннее состояние объекта, но не так, чтобы это было заметно за пределами рамки рамки". Такой объект не может быть безопасно многопоточным автоматически, но он может быть автоматически мемоизирован. Существуют всевозможные интересные аннотации, которые мы могли бы поместить в код, что обеспечило бы богатую оптимизацию и более глубокое понимание. Мы можем сделать гораздо больше, чем слабая аннотация const в стиле C.

Однако я подчеркиваю, что это всего лишь спекуляция. У нас нет твердых планов по включению подобной функции в какую-либо гипотетическую будущую версию C#, если таковая вообще существует, о чем мы не объявляли ни в том, ни в другом случае. Это то, что я хотел бы увидеть, и то, чего может потребовать грядущий акцент на многоядерных вычислениях, но все это ни в коем случае не должно быть истолковано как предсказание или гарантия какой-либо конкретной функции или будущего направления развития C#.

Итак, если вы хотите просто аннотацию к локальной переменной, которая является параметром и говорит: "Значение этого параметра не меняется в течение всего метода", то, конечно, это легко сделать. Мы могли бы поддерживать локальные переменные "readonly" и параметры, которые инициализируются один раз, а их изменение в методе будет сопровождаться ошибкой компиляции. Переменная, объявленная оператором "using", уже является такой локалью; мы могли бы добавить необязательную аннотацию ко всем локалям и параметрам, чтобы они вели себя как переменные "using". Это никогда не было очень приоритетной функцией, поэтому она так и не была реализована.

58
ответ дан 24 November 2019 в 05:18
поделиться

Я считаю, что есть две причины, по которым C# не является const-корректным.

Первая - это понятность. Немногие программисты C++ понимают const-корректность. Простой пример const int arg симпатичен, но я также видел char * const * const arg - константный указатель на константные указатели на неконстантные символы. Конст-корректность в указателях на функции - это совершенно новый уровень обфускации.

Вторая причина заключается в том, что аргументы класса - это ссылки, передаваемые по значению. Это означает, что нужно иметь дело уже с двумя уровнями константности без очевидного синтаксиса. Аналогичным камнем преткновения являются коллекции (и коллекции коллекций, и т.д.).

Конст-корректность является важной частью системы типов C++. Теоретически ее можно добавить в C# как нечто, что проверяется только во время компиляции (это не нужно добавлять в CLR, и это не повлияет на BCL, если только не будет включено понятие методов-членов const).

Однако я считаю это маловероятным: вторую причину (синтаксис) будет довольно трудно решить, что сделает первую причину (понятность) еще более проблематичной.

12
ответ дан 24 November 2019 в 05:18
поделиться

Одна из причин, по которой в C # нет const корректности , заключается в том, что она не существует на уровне времени выполнения. Помните, что в C # 1.0 не было никаких функций, если они не были частью среды выполнения.

И несколько причин, по которым в CLR отсутствует понятие корректности констант, например:

  1. Это усложняет время выполнения; кроме того, в JVM этого тоже не было, а среда CLR в основном начиналась как проект по созданию среды выполнения, подобной JVM, а не среде выполнения, подобной C ++.
  2. Если есть константная корректность на уровне выполнения, в BCL должна быть константная корректность, в противном случае эта функция практически бессмысленна для .NET Framework.
  3. Но если BCL требует константной корректности, каждый язык поверх CLR должен поддерживать константную корректность (VB, JavaScript, Python, Ruby, F # и т. Д.) Этого не произойдет.

Корректность констант в значительной степени является особенностью языка, присутствующей только в C ++. Таким образом, это в значительной степени сводится к той же аргументации, почему CLR не требует проверенных исключений (что является функцией только языка Java).

Кроме того, я не думаю, что вы можете ввести такую ​​фундаментальную функцию системы типов в управляемую среду без нарушения обратной совместимости. Так что не рассчитывайте, что корректность const когда-либо войдет в мир C #.

24
ответ дан 24 November 2019 в 05:18
поделиться

const означает "константа времени компиляции" в C#, а не "readonly, но возможно изменяемая другим кодом", как в C++. Грубым аналогом const в C++ в C# является readonly, но он применим только к полям. Кроме того, в C# вообще нет понятия корректности const, подобного C++.

Обоснование трудно сказать наверняка, потому что есть много потенциальных причин, но я предполагаю, что в первую очередь это желание сохранить язык простым, а во вторую - неопределенные преимущества реализации этого.

5
ответ дан 24 November 2019 в 05:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: