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



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



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



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

4 ответов:

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

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

Если бы const действительно сделал это, это было бы здорово. Конст так не делает. Константа-это ложь!

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

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

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

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

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

например, представьте, что вы можете "нарисовать коробку" вокруг куска кода и сказать: "я гарантия что этот кусок кода не выполняет никаких мутаций в любом поле этого класса " таким образом, который может быть проверен компилятором. Или нарисуйте коробку с надписью " Это чисто метод изменяет внутреннее состояние объекта, но не каким-либо образом, который можно наблюдать вне коробки". Такой объект не может быть безопасно многопоточным автоматически, но это может быть автоматически memoized. Есть все виды интересных аннотаций, которые мы могли бы поставить код, который позволит богатую оптимизацию и более глубокое понимание. мы можем сделать намного лучше, чем слабый c-стиль const аннотации.

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

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

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

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

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

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

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

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

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

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

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

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

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

Comments

    Ничего не найдено.