webentwicklung-frage-antwort-db.com.de

Gibt es ein "String.Format", das benannte Eingabeparameter anstelle von Indexplatzhaltern akzeptieren kann?

Das weiß ich

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

Aber ich will sowas

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

In C # 6 können Sie String-Interpolation verwenden:

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

Wie Doug Clutter in seinem Kommentar erwähnt, unterstützt die String-Interpolation auch Format-String . Sie können das Format ändern, indem Sie es nach einem Doppelpunkt angeben. Das folgende Beispiel gibt eine Zahl mit einem Komma und zwei Dezimalstellen aus:

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

Wie Bas in seiner Antwort erwähnt, unterstützt die String-Interpolation keine Template-Strings. Eigentlich hat es keine eingebaute Unterstützung dafür. Glücklicherweise existiert es in einigen großartigen Bibliotheken.


SmartFormat.NET unterstützt beispielsweise benannte Platzhalter:

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; }
}

Es ist verfügbar auf NuGet .


Moustache ist auch eine großartige Lösung. Bas hat seine Profis gut in seiner Antwort beschrieben.

136

Wenn Sie eine lokale Variable zuweisen möchten, die die Daten enthält, die Sie zum Ersetzen der Vorlagenparameter verwenden, können Sie die Funktion C # 6.0 Zeichenfolgeninterpolation verwenden.

Das Grundprinzip besteht darin, dass Sie auf der Grundlage von Eingabedaten eine relativ fortschrittliche String-Ersetzungslogik ausführen können.

Einfaches Beispiel:

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

Komplexes Beispiel:

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

Nachteile:

  • Keine Unterstützung für dynamische Vorlagen (z. B. aus einer Ressourcendatei)

(Haupt-) Vorteile:

  • Es erzwingt Kompilierungszeitprüfungen für Ihre Vorlagenersetzung.

Eine nette Open-Source-Lösung mit fast der gleichen Syntax ist Moustache . Es hat zwei verfügbare C # -Implementierungen von dem, was ich finden konnte - mustache-sharp und Nustache .

Ich habe mit mustache-sharp Gearbeitet und festgestellt, dass es nicht die gleiche Leistung wie die String-Interpolation hat, aber nahe kommt. Z.B. Sie können Folgendes tun (von seiner Github-Seite gestohlen).

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}}
29
Bas

Wenn in Ihrem Projekt C # 6 nicht verfügbar ist, können Sie Linqs .Aggregate () verwenden:

    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()));

Wenn Sie etwas wollen, das der spezifischen Syntax in der Frage entspricht, können Sie eine ziemlich einfache Klasse basierend auf Aggregate zusammenstellen:

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()));
    }

}

Verwendbar wie:

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);

Beachten Sie, dass dies ein klarer Code ist, der im Hinblick auf die Leistung leicht verständlich ist.

25
Chakrava

Mit C # 6 können Sie String-Interpolation verwenden, um Variablen direkt in einen String einzufügen.

Beispielsweise:

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

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

Beachten Sie, die Verwendung des Dollarzeichens ($) vor dem Zeichenfolgeformat.

18
Steve

Warum also nicht einfach ersetzen?

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

Es gibt keine eingebaute Möglichkeit, dies zu tun, aber Sie können eine Klasse schreiben, die dies für Sie erledigt.
So etwas kann Ihnen den Einstieg erleichtern:

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();
    }
}

Beachten Sie, dass in diesem Beispiel keine Parameternamenkonvention erzwungen wird. Dies bedeutet, dass Sie Ihre Parameternamen sehr sorgfältig auswählen sollten, da Sie sonst möglicherweise Teile der Zeichenfolge ersetzen, die Sie nicht beabsichtigt haben.

7
Zohar Peled

string-Interpolation ist eine gute Lösung, erfordert jedoch C # 6.

In diesem Fall verwende ich 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();
5
ehh

Sie können Ausdrücke auch mit der Zeichenfolgeninterpolation in C # 6 verwenden:

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

Dies wird als Interpolated String bezeichnet. Hierbei handelt es sich im Wesentlichen um eine Vorlagenzeichenfolge, die Ausdrücke enthält.

2
Matt.Mull