Строчная интерполяция с использованием именованных параметров в С# 6
Учитывая, что у меня есть строка ресурсов метаданных, хранящаяся в моей базе данных, которая будет возвращаться следующим образом:
var pageTitle = "Shop the latest {category1} Designer {category2} {category3} at www.abc.com";
И я хочу заменить {placeholders}
на переменную values
;
var category1 = "womenswear";
var category2 = "dresses";
var category3 = "cocktail dresses";
Я пробовал, не повезло;
var newTitle = $"pageTitle, category1, category2, category3";
var newTitle = $(pageTitle, category1, category2, category3);
Я знаю, что я мог бы использовать string.Replace()
, у которого есть накладные расходы на производительность. Кто-нибудь знает, как это можно сделать эффективно с использованием последней интерполяции строк С#?
Ответы
Ответ 1
Я знаю, что могу использовать string.Replace(), у которого есть служебные служебные данные
Всего наносекунд. Вы не должны оптимизировать преждевременно.
Как сказано, функция интерполяции строк С# 6 происходит во время компиляции. Если вы хотите сделать это во время выполнения, вам придется использовать замену строк.
Я предполагаю, что ваши строки отформатированы так, чтобы упростить редактирование и не иметь фиксированного порядка замены, поэтому просто выполните это:
var input = "Shop the latest {category1} Designer {category2} {category3} at www.abc.com";
var category1 = "womenswear";
var category2 = "dresses";
var category3 = "cocktail dresses";
var result = input.Replace("{category1}", category1)
.Replace("{category2}", category2)
.Replace("{category3}", category3);
Это будет работать. Вы также можете сохранить ваши замещающие значения в словаре и перебрать ключи, чтобы заменить ключ значением.
Ответ 2
Здесь вы не можете использовать интерполяцию строк. Строковая интерполяция - это метод перезаписи времени компиляции для string.Format
, который является решением, которое вы должны использовать:
var newTitle = string.Format("{0}, {1}, {2}, {3}", pageTitle, category1, category2, category3);
Или string.Join
:
var newTitle - string.Join(", ", new string[] { pageTitle, category1, category2, category3 });
Поскольку вы загружаетесь из базы данных, в вашем случае может быть лучше использовать string.Replace
.
Ответ 3
Хотя .NET не предлагает встроенную возможность для этого, вы можете легко создать довольно хорошую реализацию с регулярным выражением:
public static string Format(string formatWithNames, IDictionary<string,object> data) {
int pos = 0;
var args = new List<object>();
var fmt = Regex.Replace(
formatWithNames
, @"(?<={)[^}]+(?=})"
, new MatchEvaluator(m => {
var res = (pos++).ToString();
var tok = m.Groups[0].Value.Split(':');
args.Add(data[tok[0]]);
return tok.Length == 2 ? res+":"+tok[1] : res;
})
);
return string.Format(fmt, args.ToArray());
}
Идея состоит в том, чтобы заменить имена последовательными числами (см. sb.Append(pos++)
), построить массив параметров объекта (см. args.Add(data[tok[0]])
) и передать результат в string.Format
для использования возможностей форматирования string
.
Теперь вы можете передать свой ресурс этому Format
вместе со словарем пар ключ-значение и получить строку, форматированную с использованием встроенных возможностей форматирования .NET:
var x = new Dictionary<string,object> {
{"brown", 1}
, {"jumps", 21}
, {"lazy", 42}
};
Console.WriteLine("{0}", Format("Quick {brown} fox {jumps:C} over the {lazy:P} dog", x));
Обратите внимание, что перед строковым литералом нет $
, поэтому здесь нет встроенной интерполяции С#.
Отпечатает
Quick 1 fox $21.00 over the 4,200.00 % dog
Подход основан на идее Скотта Гензельмана, за исключением того, что форматирование выполняется по-другому.
Демоверсия
Ответ 4
Если вы не хотите использовать замену строк, вам нужно либо использовать оригинальный синтаксис форматирования:
var pageTitle = "Shop the latest {0} Designer {1} {2} at www.abc.com";
var category1 = "womenswear";
var category2 = "dresses";
var category3 = "cocktail dresses";
var newTitle = string.Format(pageTitle, category1, category2, category3);
или поместите строку форматирования после переменных:
var category1 = "womenswear";
var category2 = "dresses";
var category3 = "cocktail dresses";
var newTitle = $"Shop the latest {0} Designer {0} {0} at www.abc.com";
Интерполяция строк преобразуется в вызов string.Format
во время компиляции, поэтому нет способа сделать строку форматирования переменной во время выполнения.