Mehrzeiliges C # -interpoliertes Zeichenfolgenliteral

77

C # 6 bietet Compiler-Unterstützung für interpolierte String-Literale mit Syntax:

var person = new { Name = "Bob" };

string s = $"Hello, {person.Name}.";

Dies ist ideal für kurze Zeichenfolgen. Wenn Sie jedoch eine längere Zeichenfolge erstellen möchten, muss diese in einer einzelnen Zeile angegeben werden.

Mit anderen Arten von Zeichenfolgen können Sie:

    var multi1 = string.Format(@"Height: {0}
Width: {1}
Background: {2}",
        height,
        width,
        background);

Oder:

var multi2 = string.Format(
    "Height: {1}{0}" +
    "Width: {2}{0}" +
    "Background: {3}",
    Environment.NewLine,
    height,
    width,
    background);

Ich kann keinen Weg finden, dies mit String-Interpolation zu erreichen, ohne alles in einer Zeile zu haben:

var multi3 = $"Height: {height}{Environment.NewLine}Width: {width}{Environment.NewLine}Background: {background}";

Mir ist klar, dass Sie in diesem Fall \r\nanstelle von Environment.NewLine(weniger portabel) verwenden oder es an einen lokalen Standort ziehen können, aber es wird Fälle geben, in denen Sie es nicht unter eine Zeile reduzieren können, ohne die semantische Stärke zu verlieren.

Ist es einfach so, dass die String-Interpolation nicht für lange Strings verwendet werden sollte?

Sollten wir nur Zeichenfolgen StringBuilderfür längere Zeichenfolgen verwenden?

var multi4 = new StringBuilder()
    .AppendFormat("Width: {0}", width).AppendLine()
    .AppendFormat("Height: {0}", height).AppendLine()
    .AppendFormat("Background: {0}", background).AppendLine()
    .ToString();

Oder gibt es etwas eleganteres?

Drew Noakes
quelle
@DmytroShevchenko, ich habe darüber nachgedacht. Ich war mir jedoch nicht sicher, ob ich Ihre akzeptieren sollte, als ich sah, wie Sie die am besten bewertete Antwort von dem von Ric geposteten Link kopierten / einfügten und sie dann so bearbeiteten, dass sie anders aussah. Das alles geschah innerhalb von 5 Minuten, sodass die Änderungen nicht sichtbar sind. Ihre Antwort ist technisch korrekt, aber ich hatte das Gefühl, Sie hätten es gutschreiben sollen. Eigentlich würde ich Ric's Kommentar gerne akzeptieren, aber das ist nicht möglich.
Drew Noakes
@DrewNoakes Ihre Frage wurde als Duplikat der von Ric verlinkten Frage markiert. Ric war derjenige, der es auch markiert hat. Es ist also nicht erforderlich, meiner Antwort eine weitere Instanz dieses Links hinzuzufügen. Wenn Sie nicht einverstanden sind, würde ich Ihre Argumentation begrüßen. Und natürlich habe ich den Code in meiner Antwort bearbeitet. Der Grund war zwar nicht, es anders aussehen zu lassen, sondern dem Beispiel in Ihrer Frage zu entsprechen.
Dmytro Shevchenko
@DmytroShevchenko siehe Fußzeile der Website: Benutzerbeiträge lizenziert unter cc by-sa 3.0 mit Namensnennung erforderlich
Drew Noakes
2
Abstimmung zur Wiedereröffnung. Die vermeintliche doppelte Frage fragt etwas anderes und Gegenteiliges (sie wollen Zeilenumbrüche im Quellcode, aber nicht die Zeichenfolge). Moderatoren, lesen Sie die Fragen sorgfältig durch, bevor Sie sie schließen!
Colonel Panic

Antworten:

148

Sie können kombinieren $und @zusammen ein mehrzeiliges interpoliertes Zeichenfolgenliteral erhalten:

string s =
$@"Height: {height}
Width: {width}
Background: {background}";

Quelle: Lange String-Interpolationslinien in C # 6 (Danke an @Ric für das Finden des Threads!)

Dmytro Shevchenko
quelle
6
Ich hatte dies als @ $ (umgekehrt) versucht und es funktionierte nicht, also dachte ich, dass sie nicht kombiniert werden konnten. Es kam mir nicht in den Sinn, es anders zu versuchen.
Kencordero
2
Ab C # 8.0 können Sie die Token $ und @ in beliebiger Reihenfolge verwenden: Sowohl $ @ "..." als auch @ $ "..." sind gültige interpolierte wörtliche Zeichenfolgen. In früheren C # -Versionen muss das $ -Token vor dem @ -Token erscheinen.
hal9000
9

Ich würde wahrscheinlich eine Kombination verwenden

var builder = new StringBuilder()
    .AppendLine($"Width: {width}")
    .AppendLine($"Height: {height}")
    .AppendLine($"Background: {background}");
Sara
quelle
Könnte der Downvoter irgendwelche Einblicke geben? Ich sehe keine Probleme damit. Gibt es ein Problem?
Sara
Für die Aufzeichnung habe ich Sie tatsächlich positiv bewertet. Es kann Fälle geben, in denen dies besser lesbar ist. Der einzige Nachteil, den ich mir vorstellen kann, ist, dass ein paar zusätzliche Objekte für den GC erstellt werden.
Drew Noakes
1
Ich denke, das ist nur in Ausnahmefällen negativ, wenn Sie nur über sehr begrenzte Ressourcen verfügen oder Tausende, wenn nicht Millionen von Zeilen anhängen müssen. Ich mag keine wörtlichen Zeichenfolgen zum Formatieren. Das Layout des Textes in der Codedatei ist für das Erscheinungsbild der Ausgabe verantwortlich. Ich bevorzuge Stringbuilder, es ist ausdrucksvoller.
Sara
Ich stimme zu, dass die Formatierung von wörtlichen Zeichenfolgen etwas hässlich ist. String.Concatkönnte hier auch eine Option sein.
Drew Noakes
Definitiv wie concat mehr als wörtlich. Das Schöne an Stringbuilder ist, dass es Linebreaks für Sie erledigt. Ich würde wahrscheinlich mit beiden in Ordnung sein.
Sara
3

Persönlich füge ich einfach eine weitere interpolierte Zeichenfolge mithilfe der Zeichenfolgenverkettung hinzu

Zum Beispiel

var multi  = $"Height     : {height}{Environment.NewLine}" +
             $"Width      : {width}{Environment.NewLine}" +
             $"Background : {background}";

Ich finde das einfacher zu formatieren und zu lesen.

Dies wird hat zusätzlichen Aufwand im Vergleich zu $ mit @“" , sondern nur in den Performance - kritischen Anwendungen wird dies spürbar. Im Speicher sind Zeichenfolgenoperationen im Vergleich zu Daten-E / A extrem billig. Das Lesen einer einzelnen Variablen aus der Datenbank dauert in den meisten Fällen hunderte Male länger.

Andrew Monteith
quelle