Почему интерполяция строк не работает со строками const

почему интерполяция строк в C# не работает со строками const? Например:

private const string WEB_API_ROOT = "/private/WebApi/";
private const string WEB_API_PROJECT = $"{WEB_API_ROOT}project.json";

С моей точки зрения, все это известно во время компиляции. Или это функция, которая будет добавлена позже?

компилятор сообщение:

выражение, назначаемое DynamicWebApiBuilder.WEB_API_PROJECT ' должен быть постоянным.

Спасибо большое!

3 ответов


интерполированные строки просто преобразуются в вызовы string.Format. Так что ваши строки читает

private const string WEB_API_PROJECT = string.Format("{0}project.json", WEB_API_ROOT);

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


С другой стороны, string объединение (простых, постоянных строковых литералов) может быть сделано компилятором, поэтому это будет работать:

private const string WEB_API_ROOT = "/private/WebApi/";
private const string WEB_API_PROJECT = WEB_API_ROOT + "project.json";

поменять const до static readonly:

private static readonly string WEB_API_PROJECT = $"{WEB_API_ROOT}project.json";

в строке инициализации (а string.Format called) при первом доступе к любому члену типа объявления.


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

CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;

Console.WriteLine($"{3.14}");

CultureInfo.CurrentCulture = new CultureInfo("cs-CZ");

Console.WriteLine($"{3.14}");

результат:

3.14
3,14

обратите внимание, что выходные данные разные, хотя выражение интерполяции строк одинаково в обоих случаях. Итак, с const string pi = $"{3.14}", это было бы неясно какой код должен генерировать компилятор.


в проекте Roslyn есть обсуждение в Рослин что завершить следующий вывод:

читать отрывок:

это не ошибка, он был явно разработан, чтобы функционировать так. То, что тебе не нравится, не делает его жуком. Строка.Формат не требуется для объединения строк, но это не так то, что ты делаешь. Ты их интерполируешь и строчишь.Формат необходимо для этого на основе спецификации и реализации how интерполяция работает в C#.

Если вы хотите объединить строки, перейдите прямо вперед и используйте тот же синтаксис, который работал с C# 1.0. Изменение реализации для поведения по-разному на основе использования дают неожиданные результаты:

  const string FOO = "FOO";
  const string BAR = "BAR";
  string foobar = $"{FOO}{BAR}";
  const string FOOBAR = $"{FOO}{BAR}"; // illegal today

  Debug.Assert(foobar == FOOBAR); // might not always be true

даже утверждение:

  private static readonly string WEB_API_PROJECT = $"{WEB_API_ROOT}project.json";

компилятор вызывает ошибку:

 "The name 'WEB_API_ROOT' does not exist in the current context". 

переменная 'WEB_API_ROOT' должна быть определена в том же контексте

Так, для вопрос OP: почему интерполяция строк не работает со строками const? Ответ: это спецификации C# 6. для более подробной информации читайте .NET Compiler Platform ("Roslyn") - интерполяция строк для C#