it-swarm.com.de

Sollte ich .ToString () verwenden, wenn ich Zeichenfolgen- und Ganzzahlvariablen in C # verkette?

int a = 1;
int b = 2;
int sum = a + b;
string expression = "Expression: " + a + " + " + b + " = " + sum;
Console.WriteLine(expression); //displays Expression 1 + 2 = 3

Sollte ich es benutzen:

string expression = "Expression: " + a + " + " + b + " = " + sum;

oder

string expression = "Expression: " + a.ToString() + " + " + b.ToString() + " = " + result.ToString();

Wird empfohlen, ToString() zu verwenden, wenn string und int verkettet werden?

19
Akainu

ToString Verwendung

Nein, Sie sollten hier nicht ToString verwenden.

Die Verkettung von Zeichenfolgen wandelt Nicht-Zeichenfolgen automatisch in Zeichenfolgen um. Dies bedeutet, dass Ihre beiden Varianten nahezu identisch sind:

Wenn einer oder beide Operanden vom Typ Zeichenfolge sind, verketten die vordefinierten Additionsoperatoren die Zeichenfolgendarstellung der Operanden.

Quelle: C # Sprachspezifikation: Additionsoperator, MSDN .

Auf der anderen Seite die erste (ohne ToString):

  • Ist kürzer zu schreiben,
  • Ist kürzer zu lesen,
  • Ist einfacher zu warten und:
  • zeigt genau die Absicht des Autors: Strings zu verketten.

Also lieber den ersten.

Unter der Haube

Interessant ist auch, was unter der Haube passiert. Eine Möglichkeit, dies anzuzeigen, besteht darin, den IL-Code in LINQPad zu überwachen. Dieses Programm:

void Main()
{
    var a = 3;
    var b = " Hello";
    var c = a + b;
    Console.WriteLine(c);
}

wird in die folgende IL übersetzt:

IL_0001:  ldc.i4.3    
IL_0002:  stloc.0     // a
IL_0003:  ldstr       " Hello"
IL_0008:  stloc.1     // b
IL_0009:  ldloc.0     // a
IL_000A:  box         System.Int32
IL_000F:  ldloc.1     // b
IL_0010:  call        System.String.Concat
IL_0015:  stloc.2     // c
IL_0016:  ldloc.2     // c
IL_0017:  call        System.Console.WriteLine

Sehen Sie, dass System.String.Concat? Das bedeutet, dass der ursprüngliche Code auch so geschrieben werden kann, was in genau dieselbe IL übersetzt wird:

void Main()
{
    var a = 3;
    var b = " Hello";
    var c = string.Concat(a, b); // This is the line which was changed.
    Console.WriteLine(c);
}

Wenn Sie die Dokumentation von string.Concat(object[]) lesen, können Sie Folgendes lernen:

Die Methode verkettet jedes Objekt in args , indem sie die parameterlose ToString -Methode dieses Objekts aufruft. Es werden keine Trennzeichen hinzugefügt.

Dies bedeutet, dass ToString redundant ist. Ebenfalls:

String.Empty Wird anstelle eines Nullobjekts im Array verwendet.

Dies funktioniert gut, wenn einige der Operanden null sind (siehe Fußnote 1).

Während im letzten Beispiel die Verkettung in string.Concat Übersetzt wurde, sollte man auch Compiler-Optimierungen hervorheben:

var a = "Hello " + "World";

wird übersetzt in:

ldstr       "Hello World"
stloc.0

Auf der anderen Seite:

var a = string.Concat("Hello ", "World");

wird übersetzt in:

ldstr       "Hello "
ldstr       "World"
call        System.String.Concat
stloc.0

Andere Alternativen

Es gibt natürlich auch andere Möglichkeiten, Zeichenfolgendarstellungen von Objekten in C # zu verketten.

  1. StringBuilder wird verwendet, wenn Sie viele Verkettungsvorgänge ausführen müssen, und hilft, die Anzahl der erstellten Zwischenzeichenfolgen zu reduzieren. Die Entscheidung, ob Sie ein StringBuilder oder eine normale Verkettung verwenden sollen, ist möglicherweise nicht einfach. Verwenden Sie einen Profiler oder suchen Sie nach relevanten Antworten für den Stapelüberlauf.

    Die Verwendung von StringBuilder hat den Hauptnachteil, dass der Code schwer zu lesen und zu warten ist. In einfachen Fällen wie dem in Ihrer Frage ist StringBuilder nicht nur schädlich für die Lesbarkeit des Codes, sondern auch in Bezug auf die Leistung nutzlos.

  2. string.Join Sollte verwendet werden, wenn Sie Trennzeichen hinzufügen müssen.

    Verwenden Sie string.Join Offensichtlich niemals mit einem leeren Trennzeichen, um Zeichenfolgen zu verketten.

  3. string.Format Kann verwendet werden, wenn das Template-Template der String-Verkettung vorgezogen wird. Einer der Fälle, in denen Sie dies möglicherweise bevorzugen, ist die Lokalisierung der Nachricht, wie in der Antwort von kunthet vorgeschlagen.

    Die Verwendung von string.Format Hat mehrere Nachteile, die es für einfache Fälle wie Ihren ungeeignet machen:

    • Bei einfachen Platzhaltern "{0}" ist oft unklar, welcher Parameter wohin geht. Es kommt häufig vor, dass die Parameter versehentlich umgekehrt oder vergessen werden. Glücklicherweise C # 6 führt schließlich ein String-Interpolation, die dieses Problem löst.

    • Die Laufzeitleistung kann sich verschlechtern. Nehmen Sie natürlich nicht an, dass string.Format immer langsamer ist. Wenn es auf die Leistung ankommt, messen Sie zwei Ansätze und bestimmen Sie anhand Ihrer tatsächlichen Ergebnisse anstelle der Annahmen, welcher schneller ist.

    • Der Code ist etwas länger zu schreiben, länger zu lesen und schwieriger zu warten, obwohl dies äußerst geringfügig ist und Sie nicht zu sehr stören sollte.


¹ Der Unterschied tritt auf, wenn eines der Objekte null ist. Ohne ToString wird ein null durch eine leere Zeichenfolge ersetzt. Mit ToString wird ein NullReferenceException ausgelöst.

33

Stattdessen sollten Sie den String-Formatierer verwenden. Es ist einfacher, Ihre Nummer in Zeichenfolgendarstellung oder Lokalisierung zu formatieren. z.B.:

string expression = string.Format("Expression: {0} + {1} = {2}", a, b, sum);

Weitere Informationen zu MSDN .

Der String-Formatierer ist jedoch weniger lesbar (und möglicherweise auch leistungsfähiger) als die String-Verkettung.

15
kunthet