Выведение типа константа в C#

В C#, следующих работах вывода типа:

var s = "abcd";

Но почему тип не может быть выведен, когда переменная - константа?

Следующие броски исключение времени компиляции:

const var s = "abcd"; // <= Compile time error: 
                      //    Implicitly-typed local variables cannot be constant
40
задан Andreas Grech 24 January 2010 в 19:33
поделиться

7 ответов

filter_by использует аргументы ключевых слов, тогда как фильтр позволяет аргументы фильтрации Pythonic, такие как фильтр (User.name == «John»)

-121)

--- 568952-

Я на самом деле надеюсь, что Lippert SPAS и смотрит на вопрос

, если есть что-то, что вы хотите привлечь мое внимание, вы можете оставить свое имя в тексте - не комментарий - И я найду это в конце концов. Или, лучше, вы можете «Tweet» в @ericlippert . Обратите внимание, что это не является соглашением о уровне обслуживания; Я делаю это в свое свободное время.

Почему тип не может быть выведен, когда переменная является константой?

«Константа» и «Переменная» представляют собой противоположности . const var дает мне удар по типу. Константа - это значение, которое никогда не меняется и не имеет местоположения хранения; Переменная - это место хранения, содержимое которого меняется. Они совершенно разные, поэтому не пытайтесь объединить их. Синтаксис VAR был выбран для вызова «это вариабельная», и мы придерживаемся с ним.

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

Я был бы совершенно в порядке с предполагаемыми константами, которые не используют var :

const Pi = 3.14159;

кажется, что мне кажется хорошо. Тем не менее, я знаю, о не планах добавить это к C #.

33
ответ дан 27 November 2019 в 01:36
поделиться

В этом случае очевидно, что вы знаете, что тип ссылочного типа будет постоянным, а также довольно примитивного типа (Consts может быть только типов ценностей, или строки и т. Д.), Так что вы должны объявить этот тип, а не Используйте неявное набрав.

Другими словами, потому что тип, очевидно, является постоянным и известным, абсолютно нет причин использовать var.

Неявно напечатанные локальные переменные только необходимо для хранения анонимных Типы. Во всех остальных случаях они просто удобство. Если значение Переменная никогда не меняется, просто дайте Это явный тип. Пытаясь использовать реконструкции модификатора с неявно напечатанный локальный будет генерировать CS0106.

http://msdn.microsoft.com/en-us/library/bb310881.aspx

Ошибка компилятора CS0822

Чтобы исправить эту ошибку, если вам требуется переменная быть постоянной или Readonly, дайте ему явный тип.

2
ответ дан 27 November 2019 в 01:36
поделиться

Это всего лишь догадка, но я думаю, что причина может быть в том, что при компиляции значения const помещаются в метаданные (что имеет тонкие последствия, все, что у них есть). Интересно, может быть, у компилятора есть некоторые проблемы с тем, как преобразовать var в метаданные.

В Richter's CLR VIA C# (стр. 177),

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

Далее он отмечает, что это означает, что по этой причине нельзя получить ссылку на память константы. Чтобы сделать это немного более очевидным, в psuedo C#, если ассемблер A определяет const:

//Assembly A, Class Widget defines this:
public static const System.Decimal Pi = 3.14

, то у вас есть потребитель A:

//somewhere in the Program.exe assembly
decimal myCircleCurcum = 2 * Widget.pi

результирующий скомпилированный IL программы.exe сделал бы что-то вроде этого псевдокода:

// pseudo-IL just to illustrate what would happen to the const
myCircleCurcum = 2*3.14

обратите внимание, что потребляющая ассемблер не имеет никакого представления о том, что десятичная цифра 3.14 вообще имеет какое-нибудь отношение к ассемблеру A - это к program.exe буквальное значение. Для меня это разумный способ для компилятора C# действовать--в конце концов, Assembly A объявила явно, что pi является константой (это означает, что значение раз и навсегда pi=3.14). Но, осмелюсь предположить, что 99% разработчиков C# не понимают последствий этого & могут по прихоти изменить значение pi на 3.1415.

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

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

если сборка A определяет:

decimal const pi = 3.14

, то вы собираете ее, а затем другие сборки потребляют ее, если вы затем меняете сборку A:

decimal const pi = 3.1415

и восстанавливаете сборку A, потребитель сборки A все равно будет иметь старое значение 3.14! почему? потому что исходное 3. 14 была определена как константа, что означает, что потребителям сборки A было сказано, что значение не изменится - так что они могут испечь это значение pi в своих собственных метаданных (если вы перестроите потребителя сборки A, то он получит новое значение pi в своих метаданных). Опять же, я не вижу в этом проблемы с тем, как CSC обрабатывает константы - это просто то, что разработчики, вероятно, не ожидают, что константа не может быть безопасно изменена при некоторых обстоятельствах, где она может быть безопасно изменена в других. Safe: ни один потребитель никогда не будет иметь ссылки только на .dll (т.е. они всегда будут собираться из исходных текстов КАЖДОЕ ВРЕМЯ), небезопасно: потребители понятия не имеют о том, когда изменяется исходный текст вашей сборки с константой, определяемой константой. Вероятно, в .NET документации следует более четко указать, что константа означает, что вы не можете изменить значение в sourcecode

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

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

12
ответ дан 27 November 2019 в 01:36
поделиться

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

Чтобы объяснить, что я имею в виду, рассмотрим VB.

В VB 9 вы также не могли вывести константы, но это было просто ограничение компилятора. В VB 10 они смогли добавить константные вывод типа, не принудительные изменения на язык на язык.

1
ответ дан 27 November 2019 в 01:36
поделиться

Краткий ответ - потому что дизайнеры языка (Microsoft) так говорят.

Из MSDN :

Ошибка компилятора CS0822

Сообщение об ошибке : неявно набранные местные жители не может быть const

неявно напечатанные локальные переменные только необходимо для хранения анонимных Типы. Во всех остальных случаях они просто удобство. Если значение Переменная никогда не меняется, просто дайте Это явный тип. Пытаясь использовать реконструкции модификатора с неявно напечатанный локальный будет генерировать CS0106.

Чтобы исправить эту ошибку

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

7
ответ дан 27 November 2019 в 01:36
поделиться

IMO VAR Основная цель - разрешить анонимные типы (тип неизвестен, с VAR вы можете объявить переменную для его хранения). Более распространенное использование сейчас - писать меньше кода;). Как объясняют здесь Если вы знаете тип и значение (которое не изменится) просто напишите тип.

0
ответ дан 27 November 2019 в 01:36
поделиться

Я согласен с Эриком в том, что это уродливо, как грех:

const var s = "abcd"

Но почему не просто это?

const s = "abcd"

Мне кажется разумным синтаксисом.

11
ответ дан 27 November 2019 в 01:36
поделиться
Другие вопросы по тегам:

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