Интерполяция строк с переменной формата

Я могу сделать это:

var log = string.Format("URL: {0}", url);

или даже вот так

var format = "URL: {0}";
...
var log = string.Format(format, url);

У меня есть format, определенный где-то еще, и я использую переменную format, а не встроенную строку.

В C# 6 это кажется невозможным:

var format = $"URL: {url}"; // Error url does not exist
...
var url = "http://google.com";
...
var log = $format; // The way to evaluate string interpolation here

Можно ли вообще использовать интерполяцию строк с объявленной ранее переменной?

С# 6, похоже, интерполирует встроенную строку во время компиляции. Однако рассмотрите возможность использования этой функции для локализации, определите формат в конфигурации или просто установите формат const в классе.


person CallMeLaNN    schedule 02.09.2015    source источник
comment
Вы не можете этого сделать. Просто используйте string.Format.   -  person SLaks    schedule 02.09.2015
comment
Вы должны использовать «старый способ», который вы использовали, или обернуть его в частный метод.   -  person Andrew B    schedule 02.09.2015


Ответы (6)


Нет, вы не можете использовать интерполяцию строк с чем-то другим, кроме строкового литерала, поскольку компилятор создает строку «обычного» формата, даже когда вы используете интерполяцию строк.

Потому что это:

string name = "bar";
string result = $"{name}";

компилируется в это:

string name = "bar";
string result = string.Format("{0}", name);

строка во время выполнения должна быть строкой "обычного" формата, а не строковым эквивалентом интерполяции.

Вместо этого вы можете использовать старый добрый String.Format.

person i3arnon    schedule 02.09.2015
comment
Я согласился. Я подумал, что логически отображение "{name}" в "{0}" может быть выполнено в первую очередь во время выполнения, но параметры string.Format должны быть скомпилированы встроенными. Поэтому я не могу просто динамически вводить новые {name2} в переменную. - person CallMeLaNN; 02.09.2015
comment
но по крайней мере он должен принимать const string. Затем компилятор может найти токен "{...}" и создать параметры string.Format. В любом случае, ничего страшного. - person CallMeLaNN; 02.09.2015
comment
@CallMeLaNN это будет работать только, если константа будет определена внутри метода, чтобы компилятор мог разрешить (и проверить) заполнители. В противном случае, как компилятор может решить, является ли константная строка уровня класса допустимой, если ее заполнители существовали только внутри методов? - person Panagiotis Kanavos; 11.09.2015

Один из способов обойти это — использовать лямбду, содержащую интерполированную строку. Что-то типа:

Func<string, string> formatter = url => $"URL: {url}";
...
var googleUrl = "http://google.com";
...
var log = formatter(googleUrl);

В C# 7.0 вы могли бы использовать локальную функцию вместо лямбда, чтобы сделать код немного проще и эффективнее:

string formatter(string url) => $"URL: {url}";
...
var googleUrl = "http://google.com";
...
var log = formatter(googleUrl);
person svick    schedule 02.09.2015

Интерполяция строк — это функция компилятора, а не библиотеки.

Дырки - это не имена, а выражения:

var r = new Rectangle(5, 4);
var s = $"area: {r.Width + r.Heigh}":

Как бы вы сделали это для локализации, как вы собираетесь?

Даже r существует только во время компиляции. В IL это просто позиция в стеке переменных метода.

Я сделал то, что вы намеревались сделать для ресурсов и файлов конфигурации.

Поскольку у вас может быть только конечный набор «переменных» для замены, я создал массив (или словарь, если хотите) и использовал регулярное выражение для замены имен в дырах его индексом. То, что я сделал, даже позволило использовать спецификаторы формата.

person Paulo Morgado    schedule 02.09.2015
comment
Часть локализации "area: " в вашем примере. Однако +1 за упоминание о выражении. - person CallMeLaNN; 03.09.2015

Предполагается, что это комментарий к ответу от i3arnon, но у меня нет репутации :-( : Но для тех, кто приходит в эту старую ветку, в string.Format формат может быть переменной:

string name = "bar";
string format = "{0}";
string result = string.Format(format, name);

работает.

person Michael Schreiber    schedule 26.12.2019

Скорее идея, чем ответ.

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

var format = "URL: ";
...
var url = "http://google.com";
...
var result= $"{format} {url}";

У меня есть реальный проект, в котором я должен много делать что-то вроде этого:

var label = "Some Label";
var value = "SomeValue";

//both label & value are results of some logic

var result = $"{label}: {value}";
person Dimskiy    schedule 26.07.2018

Кажется, что вы можете сделать это так:

var googleUrl = "http://google.com";
var url = $"URL: {googleUrl}";

System.Console.WriteLine(url);

Дополнительные сведения можно найти на странице https://msdn.microsoft.com/en-us/library/dn961160.aspx

person ivan    schedule 02.09.2015