Почему C # не предлагает константу, сродни C ++? - PullRequest
14 голосов
/ 09 февраля 2009

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

Почему компилятору C # так трудно поддерживать следующее:

  1. Функции-члены отмечены const.
  2. Ссылки на типы данных (кроме строк), помеченные const, с помощью которых можно вызывать только const функции-члены?

Полагаю, было бы очень полезно, если бы C # поддерживал это. С одной стороны, это действительно поможет, казалось бы, широко распространенному гею, с которым программисты C # возвращают голые ссылки на личные данные (по крайней мере, это то, что я видел на своем рабочем месте).

Или в C # уже есть что-то эквивалентное, чего мне не хватает? (Я знаю о ключевых словах readonly и const, но на самом деле они не служат вышеуказанной цели)

Ответы [ 5 ]

17 голосов
/ 09 февраля 2009

Я подозреваю, что есть некоторые практические причины и некоторые теоретические причины:

  • Должно ли постоянство применяться к объекту или эталону ? Если это в ссылке, это должно быть только во время компиляции, или как бит внутри самой ссылки? Может ли что-то еще, что имеет неконстантную ссылку на тот же объект, возиться с ним под капотом?
  • Хотели бы вы иметь возможность отбросить его, как вы можете в C ++? Это не очень похоже на то, что вы хотели бы на управляемой платформе ... но как насчет тех случаев, когда это имеет смысл в C ++?
  • Синтаксис становится сложным (IMO), когда в объявлении задействовано более одного типа - подумайте о массивах, обобщениях и т. Д. Может быть трудно понять, какой именно бит является константным.
  • Если вы не можете выбросить это, каждый должен сделать это правильно . Другими словами, и .NET Framework-типы, и любые другие сторонние библиотеки, которые вы используете, должны делать все правильно, или у вас остаются неприятные ситуации, когда ваш код не может делать правильные вещи из-за тонкой проблемы с константность.

Есть большой вопрос, почему он не может быть поддержан сейчас хотя:

  • Обратная совместимость: нет способа, чтобы все библиотеки были правильно перенесены в него, что делает его практически бесполезным: (

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

РЕДАКТИРОВАТЬ: Был спор об этом ярости в сообществе Java целую вечность. Довольно много комментариев к соответствующей ошибке , которые могут вас заинтересовать.

6 голосов
/ 09 февраля 2009

Как уже говорил Джон, правильность констант не так проста, как может показаться. C ++ делает это одним способом. D делает это другим (возможно, более правильным / полезным) способом. C # заигрывает с этим, но не делает ничего более дерзкого, как вы обнаружили (и, вероятно, никогда не получится так, как Джон снова прикрыл).

Тем не менее, я считаю, что многие из "теоретических причин" Джона решены в модели Д.

В D (2.0) const работает во многом как C ++, за исключением того, что он полностью транзитивен (поэтому const, примененный к указателю, будет применяться к указанному объекту, любым элементам этого объекта, любым указателям, которые этот объект имел, объектам, которые они указывает на и т. д.) - но очевидно, что это только применяется из переменной, которую вы объявили const (поэтому, если у вас уже есть неконстантный объект, и вы берете на него указатель const, переменная const все еще может изменять состояние).

D вводит другое ключевое слово - инвариант - которое применяется к самому объекту. Это означает, что ничто не может изменить состояние после инициализации.

Прелесть этой схемы в том, что метод const может принимать как const, так и инвариантные объекты. Поскольку инвариантные объекты - это хлеб функциональности, и метод const можно пометить как «чистый» в функциональном смысле, даже если он может использоваться с изменяемыми объектами.

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

Хотелось бы, чтобы порт D работал на .Net VM, хотя: -)

5 голосов
/ 09 февраля 2009

г. Хелсберг , разработчик языка C #, уже ответил на этот вопрос:

http://www.artima.com/intv/choicesP.html

2 голосов
/ 12 февраля 2009

Я не удивлюсь, если в будущую версию C # будут добавлены неизменяемые типы. В C # 3.0 уже были шаги в этом направлении.

Например, анонимные типы являются неизменяемыми.

Я думаю, что в результате расширений, разработанных для обеспечения параллелизма, вы, вероятно, увидите, что неизменность будет появляться все больше и больше.

0 голосов
/ 09 февраля 2009

Вопрос в том, нужна ли нам константность в C #?

  1. Я почти уверен, что JITter знает, что данный метод не повлияет на сам объект, и выполняет соответствующие оптимизации автоматически. (может быть, испуская call вместо callvirt?)

  2. Я не уверен, что мы нуждаемся в них, так как большинство плюсов constness связаны с производительностью, вы в конечном итоге в точке 1.

Кроме того, в C # есть ключевое слово readonly.

...