Подтвердить что ты не робот

Строчная интерполяция с использованием именованных параметров в С# 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(), у которого есть накладные расходы на производительность. Кто-нибудь знает, как это можно сделать эффективно с использованием последней интерполяции строк С#?

4b9b3361

Ответ 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 во время компиляции, поэтому нет способа сделать строку форматирования переменной во время выполнения.