Почему параметры const не разрешены в C #?

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

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

    ....
    static void TestMethod1(const MyClass val)
    {}
    ....
    static void TestMethod2(const int val)
    {}
    ....
93 голоса | спросил Incognito 16 J000000Friday10 2010, 12:06:55

4 ответа


0

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

ответил Eric Lippert 16 J000000Friday10 2010, 19:45:17
0

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

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

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

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

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

ответил Ruben 16 J000000Friday10 2010, 12:29:02
0

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

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

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

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

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

ответил Stephen Cleary 16 J000000Friday10 2010, 13:45:12
0

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

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

ответил Pavel Minaev 16 J000000Friday10 2010, 12:10:30

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132