Почему параметры const не разрешены в C #? - PullRequest
95 голосов
/ 16 июля 2010

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

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

    ....
    static void TestMethod1(const MyClass val)
    {}
    ....
    static void TestMethod2(const int val)
    {}
    ....

Ответы [ 4 ]

57 голосов
/ 16 июля 2010

В дополнение к другим хорошим ответам я добавлю еще одну причину, по которой не следует использовать константность в стиле 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, уже является локальной; мы могли бы добавить необязательную аннотацию ко всем локальным элементам и параметрам, чтобы они действовали как переменные «с помощью». Это никогда не было функцией с очень высоким приоритетом, поэтому она никогда не была реализована.

23 голосов
/ 16 июля 2010

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

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

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

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

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

11 голосов
/ 16 июля 2010

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

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

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

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

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

5 голосов
/ 16 июля 2010

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

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

...