16. Sep 2024
Lesedauer 5 Min.
String-Interpolation
Variablen in Zeichenketten
Das Feature gibt es schon seit C# 6. Mit C# 10 und 11 wurde es weiterentwickelt.

Das C#-Feature String-Interpolation begleitet uns nun schon ein paar Jahre. Vermutlich hat jeder Entwickler es bereits verwendet, sehr viele werden es sogar täglich nutzen. Im Lauf der Jahre hat Microsoft das Feature ausgebaut, bis hin zur Möglichkeit, individuelle Erweiterungen einzufügen. Es ist an der Zeit, sich dem Thema etwas intensiver zu widmen.Bereits seit C# 6 lässt sich ein String mit einem einfachen Dollar-Zeichen vor seiner Zeichenkette (etwa $”Treffer …”) als interpolierter String markieren (Bild 1). Anschließend kann der String beliebige Platzhalter innerhalb geschweifter Klammern (etwa {zahl}) aufnehmen, und es können beliebige Objekte übergeben werden, die .NET letztendlich zu einem String zusammenbaut.

Ein einfaches Beispiel für die String-Interpolation (Bild 1)
Autor
Wahrscheinlich, so glaube ich, ist dies die häufigste Form der String-Interpolation, die im Alltag verwendet wird. Inzwischen hat Microsoft das Feature allerdings noch um einige Funktionen erweitert – aber der Reihe nach.
String-Interpolation und Formatierungen
Die Sprache C# hat, wie alle anderen Sprachen auch, eine Syntax – also ein Regelwerk, das festlegt, was wie und in welcher Reihenfolge geschrieben werden darf. Die Syntax der String-Interpolation hat laut Microsoft [1] die in Bild 2 gezeigte Grundform. Wie im Bild zu sehen ist, gehört auch ein [:<formatString>] dazu. Dieser steht in eckigen Klammern und ist folglich optional. Mit seiner Hilfe kann der Entwickler ein Format angeben, das bei der Umwandlung eines Objekts in einen String angewendet werden soll. Dabei kann jedes Format angegeben werden, welches das übergebene Objekt unterstützt. Bild 3 zeigt ein Beispiel; die Formatangaben stehen, wie von der Syntax vorgegeben, hinter einem Doppelpunkt.
C#-Syntax der String-Interpolation (Bild 2)
Autor

Der Format-String hinter dem Doppelpunkt gibt das gewünschte Ausgabeformat an (Bild 3)
Autor
Die Erweiterung um RawString Literals
Mit Version 11 von C# wurde das Feature um Raw String Literals erweitert. Seither können auch lange Texte in C#-Code eingebaut werden, denen an beliebiger Stelle anschließend ein Wert übergeben wird (Bild 4).
Raw String kombiniert mit String-Interpolation (Bild 4)
Autor
Ebenfalls seit C# 11 dürfen innerhalb der String-Interpolation beliebig viele Zeilenumbrüche verwendet werden. Das mag zwar ab und zu recht schick aussehen, verleitet gelegentlich aber zu abenteuerlichen Konstrukten, wie dem in Bild 5.

Abenteuer-liche String-Interpolation mit Zeilenumbrüchen (Bild 5)
Autor
Was lange Zeit im Verborgenen (für mich zumindest) lag, ist die Frage nach der Culture bei der Formatierung. Klarerweise verwendet die String-Interpolation beim Zusammenbauen des Strings automatisch die CultureInfo.Currentculture sowie alle .NET-Funktionen, die im Zusammenhang damit stehen. Es stellt sich jedoch die Frage, wie man erzwingen kann, dass bei Bedarf für eine spezifische String-Ausgabe eine andere als die Standard-Culture verwendet wird. An dieser Stelle hat Microsoft nachgebessert und seit .NET 6 eine Methode in die Stammklasse string eingebaut, der eine Culture übergeben werden kann, die dann für die Formatierung des Textes verwendet wird – siehe Bild 6.

Übergabe einer Culture (Bild 6)
Autor
Jetzt wirds abenteuerlich
Microsoft hat aber noch weiter nachgebessert, und zwar bereits mit C# 10 und .NET 6: Hinzugekommen ist damals ein Pattern namens Interpolated String Handler.Damit können Entwickler angeben, wie das Feature String-Interpolation funktionieren soll, und – falls gewünscht – sogar eigene Erweiterungen einbauen. Setzen wir ein Dollar-Zeichen vor einen String, so baut der Compiler je nach Situation ein wenig „Magie“ ein. Auf Basis des vorangestellten Typs wird versucht, den korrekten InterpolatedStringHandler zu finden. Deswegen können wir jederzeit anstelle von string den DefaultInterpolatedStringHandler auch direkt verwenden – der, wie der Name vermuten lässt, der Standardhandler im .NET-Bereich ist. Die direkte Verwendung des DefaultInterpolatedStringHandler bringt allerdings keinen wirklichen Mehrwert, außer man möchte zum Beispiel erzwingen, dass einer Methode ein interpolierter String übergeben wird (Bild 7).
Grundstruktur der Klasse MyFormattedString (Bild 7)
Autor
Spannender ist der FormattableString, der durch Aufruf von ToString() den korrekten String zusammenbaut. Dabei hat der FormattableString den Vorteil, dass er die Argumente und das Format noch kennt. Wer also zu einem späteren Zeitpunkt das Format noch einmal eruieren will, kann diesen Datentyp nutzen. Das eigentliche Grundformat ist mit der Klasse MyFormattedString aus Bild 7 ersichtlich. Der Compiler hat am Ende keine wirkliche Ahnung, was da auf ihn zukommt. Deswegen sind einige Regeln einzuhalten: Wichtig ist, dass der InterpolatedStringHandler mit einem Attribut markiert wird. Außerdem wird verlangt, dass ein Konstruktor vorhanden ist, dem die Länge des Textes sowie die Zahl der Argumente übergeben werden. Anschließend wird entweder die Methode AppendLiteral für einen reinen Text aufgerufen oder AppendFormatted für ein Objekt, das übergeben wird. Mit diesem Konstrukt lässt sich ein eigenes Regelwerk definieren, das festlegt, wie aus diesem MyFormattedString ein String gemacht wird – am Ende wird die Methode ToString() überschrieben.
Ein praktisches Beispiel
Man könnte nun zu diesem Feature die kritische Frage stellen: „Wer braucht denn so was?“ Tatsächlich gibt es aber bereits Frameworks wie EF Core, die sich dieses Feature zunutze machen, siehe Bild 8. Dort nehmen Aufrufe, die direkt mit der Datenbank und SQL interagieren, nur noch einen FormattableString entgegen, damit Microsoft die Argumente mit DbParameters an den eigentlichen DbCommand übergeben und damit die gefürchtete SQL-Injection verhindern kann.
EF Core mit FormattableString für das Generieren von SQL-Statements (Bild 8)
Autor
Fazit
String-Interpolation ist ein altbekanntes Feature, das in seiner Grundform von den meisten Entwicklern im Alltag verwendet wird. Wirft man einen frischen Blick auf das Feature, wird klar, dass sich im Lauf der Jahre so einiges getan hat und man in der täglichen Praxis von der einen oder anderen Erweiterung profitieren kann.Fussnoten
- Microsoft Learn, String-Interpolation, http://www.dotnetpro.de/SL2410NETirol1