Строка С# должна быть константой

Я писал этот кусок кода:

public const int MAJOR_VERSION = 3;
public const int MINOR_VERSION = 3;
public const string VERSION_STRING = $"v.{MAJOR_VERSION}{MINOR_VERSION}";

И, что неудивительно, компилятор жаловался:
"Выражение, присваиваемое VERSION_STRING, должно быть постоянным"

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

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

Заранее спасибо. :)


person ワイきんぐ    schedule 23.01.2020    source источник
comment
$"..." - это вызов метода string.Format/Concat... так что это не константа...   -  person Selvin    schedule 23.01.2020
comment
См. github.com/dotnet/csharplang/issues/2951.   -  person canton7    schedule 23.01.2020
comment
weblog.west- ветер.com/posts/2016/Dec/27/. На первый взгляд интерполированные строки кажутся простым способом создания строковых шаблонов, оценивающих выражения. Но важно понимать, что интерполяция строк в C# — это просто синтаксический сахар, созданный компилятором, который динамически генерирует код string.Format() с параметризованными выражениями времени компиляции.   -  person Charleh    schedule 23.01.2020
comment
Отвечает ли это на ваш вопрос? Почему интерполяция константной строки приводит к компилятору ошибка? что является первым результатом поиска в Google: строка C# должна быть постоянной интерполяцией   -  person Selvin    schedule 23.01.2020


Ответы (4)


Когда мы используем ключевое слово const, то значения интерполяции строк должны быть константой времени компиляции. Использование интерполяции строк требует выполнения кода .NET, что может произойти только во время работы приложения, а не во время компиляции.

Поэтому вместо const вы можете использовать static readonly:

public const int MAJOR_VERSION = 3;
public const int MINOR_VERSION = 3;
public static readonly string  VERSION_STRING = $"v.{MAJOR_VERSION}{MINOR_VERSION}";
person StepUp    schedule 23.01.2020

У вас есть эта ошибка, потому что символ $ перед строкой является ярлыком для вызова String.Format(). String.Format() является методом, его возвращаемое значение не может быть сохранено в константе.

person nalka    schedule 23.01.2020

Строка, которую вы пытаетесь установить, не является постоянным значением, поскольку она получена из других переменных/констант.

Вместо этого попробуйте статический режим только для чтения

public static readonly string VERSION = $"v.{MAJOR_VERSION}{MINOR_VERSION}";
person jason.kaisersmith    schedule 23.01.2020
comment
Доступ к public const string FOO = "bar"; и public readonly string FOO = "bar"; осуществляется по-разному. для const вы используете ClassName.FOO. Для readonly вы используете instantiatedObject.FOO. const — это static, readonly — это часть экземпляра - person Cid; 23.01.2020

Чтобы объяснить, почему команда C# не могла сделать это функцией времени компиляции:

Результат $"{}" или string.Format() может варьироваться во время выполнения в зависимости от культуры компьютера, на котором он работает в данный момент.

Например, см. здесь, что VERSION является константой, но результирующие строки различны.

const double VERSION = 3.3;

string withDots   = String.Format(new System.Globalization.CultureInfo("en-GB"), "{0:N}", VERSION));
// "3.3"

string withCommas = String.Format(new System.Globalization.CultureInfo("fr-FR"), "{0:N}", VERSION));
// "3,3"
person Buh Buh    schedule 23.01.2020