Есть "строки.Формат", который может принимать именованные входные параметры вместо заполнителей индекса? [дубликат]


этот вопрос уже есть ответ здесь:

  • Переменных C# в строках 3 ответы
  • Каков хороший способ выполнения шаблонов строк в .NET? 12 ответов

вот что я знаю

str = String.Format("Her name is {0} and she's {1} years old", "Lisa", "10");

но я хочу что-то вроде

str = String("Her name is @name and she's @age years old");
str.addParameter(@name, "Lisa");
str.addParameter(@age, 10);
9 70

9 ответов:

В C# 6 Вы можете использовать строку интерполяции:

string name = "Lisa";
int age = 20;
string str = $"Her name is {name} and she's {age} years old";

как Даг Клаттер упомянутые в комментарии, строка интерполяции также поддерживает формат строки. Можно изменить формат, указав его после двоеточия. В следующем примере будет выведено число с запятой и 2 знака после запятой:

var str = $"Your account balance is {balance:N2}"

как Bas упомянутые в ответ, строковая интерполяция не поддерживает строку шаблона. На самом деле, он не имеет встроенной поддержки для этого. К счастью, он существует в некоторых больших библиотеках.


SmartFormat.NET например, имеет поддержку именованного заполнителя:

Smart.Format("{Name} from {Address.City}, {Address.State}", user)

// The user object should at least be like that 

public class User
{
    public string Name { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public string City { get; set; }
    public string State { get; set; }
}

он доступен на NuGet.


ус это также отличное решение. Bas описал свои плюсы хорошо в ответ.

если вы в порядке назначения локальной переменной, которая содержит данные, используемые для замены параметров шаблона, вы можете использовать C# 6.0 функции интерполяции строк.

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

простой пример:

string name = "John";
string message = $"Hello, my name is {name}."

сложный пример:

List<string> strings = ...
string summary = $"There are {strings.Count} strings. " 
  + $"The average length is {strings.Select(s => s.Length).Average()}"

недостатки:

  • нет поддержки динамических шаблонов (например, от a файл ресурсов)

(основные) преимущества:

  • он насаждает проверка времени компиляции на замену шаблона.

хорошее решение с открытым исходным кодом, который имеет почти тот же синтаксис, составляет ус. Он имеет две доступные реализации C# из того, что я мог найти - усы-острые и Nustache.

Я работал с mustache-sharp и обнаружил, что он не имеет та же мощность, что и интерполяция строк, но приближается. Например, вы можете сделать следующее (украдено с его страницы github).

Hello, {{Customer.Name}}
{{#newline}}
{{#newline}}
{{#with Order}}
{{#if LineItems}}
Here is a summary of your previous order:
{{#newline}}
{{#newline}}
{{#each LineItems}}
    {{ProductName}}: {{UnitPrice:C}} x {{Quantity}}
    {{#newline}}
{{/each}}
{{#newline}}
Your total was {{Total:C}}.
{{#else}}
You do not have any recent purchases.
{{/if}}
{{/with}}

Если у вас нет C#6, доступного в вашем проекте, вы можете использовать Linq .Aggregate ():

    var str = "Her name is @name and she's @age years old";

    var parameters = new Dictionary<string, object>();
    parameters.Add("@name", "Lisa");
    parameters.Add("@age", 10);

    str = parameters.Aggregate(str, (current, parameter)=> current.Replace(parameter.Key, parameter.Value.ToString()));

Если вы хотите, чтобы что-то соответствовало определенному синтаксису в вопросе, вы можете собрать довольно простой класс на основе Aggregate:

public class StringFormatter{

    public string Str {get;set;}

    public Dictionary<string, object> Parameters {get;set;}

    public StringFormatter(string p_str){
        Str = p_str;
        Parameters = new Dictionary<string, object>();
    }

    public void Add(string key, object val){
        Parameters.Add(key, val);
    }

    public override string ToString(){
        return Parameters.Aggregate(Str, (current, parameter)=> current.Replace(parameter.Key, parameter.Value.ToString()));
    }

}

как использовать:

var str = new StringFormatter("Her name is @name and she's @age years old");
str.Add("@name", "Lisa");
str.Add("@age", 10);

Console.WriteLine(str);

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

С C# 6 Вы можете использовать Интерполяция Строк для непосредственного добавления переменных в строку.

например:

string name = "List";
int age = 10;

var str = $"Her name is {name} and she's {age} years old";

обратите внимание, использование знака доллара ($) перед строкой формат.

Так почему бы просто не заменить?

string str = "Her name is @name and she's @age years old";
str = str.Replace("@name", "Lisa");
str = str.Replace("@age", "10");

нет встроенного способа сделать это, но вы можете написать класс, который сделает это за вас.
Что-то вроде этого может помочь вам начать:

public class ParameterizedString
{
    private string _BaseString;
    private Dictionary<string, string> _Parameters;

    public ParameterizedString(string baseString)
    {
        _BaseString = baseString;
        _Parameters = new Dictionary<string, string>();
    }

    public bool AddParameter(string name, string value)
    {
        if(_Parameters.ContainsKey(name))
        {
            return false;
        }
        _Parameters.Add(name, value);
        return true;
    }

    public override string ToString()
    {
        var sb = new StringBuilder(_BaseString);
        foreach (var key in _Parameters.Keys)
        {
            sb.Replace(key, _Parameters[key]);
        }
        return sb.ToString();
    }
}

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

интерполяция строк является хорошим решением, однако для этого требуется C#6.

в таком случае я использую StringBuilder

var sb = new StringBuilder();

sb.AppendFormat("Her name is {0} ", "Lisa");
sb.AppendFormat("and she's {0} years old", "10");
// You can add more lines

string result = sb.ToString();
    string name = "Lisa";
    int age = 20;
    string str = $"Her name is {name} and she's {age} years old";

Это называется Интерполированной Строки, который является в основном строкой шаблона, которая содержит выражения внутри него.

вы также можете использовать выражения с интерполяцией строк C#6:

string name = "Lisa";
int age = 20;
string str = $"Her name is {name} and she's {age} year{(age == 1 ? "" : "s")} old";