2015-07-31 11 views
8

Qual è lo scopo dell'utilizzo di String.Concat(Object) anziché di String.Concat(String) in C#? Perché non utilizzare semplicemente una chiamata implicita di Object.ToString() invece di passare uno object stesso che potrebbe causare il verificarsi della boxe?Scopo di String.Concat (Object) invece di String.Concat (String)

Int32 i = 5; 
String s = "i = "; 

// Boxing happens, ToString() is called inside 
Console.WriteLine(s + i); 
// Why compiler doesn't call ToString() implicitly? 
Console.WriteLine(s + i.ToString()); 

Fornisce il seguente IL.

.method private hidebysig static void MyDemo() cil managed 
{ 
    // Code size  47 (0x2f) 
    .maxstack 2 
    .locals init ([0] int32 i, [1] string s) 
    IL_0000: nop 
    IL_0001: ldc.i4.5 
    IL_0002: stloc.0 
    IL_0003: ldstr  "i = " 
    IL_0008: stloc.1 
    IL_0009: ldloc.1 
    IL_000a: ldloc.0 
    IL_000b: box  [mscorlib]System.Int32 
    IL_0010: call  string [mscorlib]System.String::Concat(object, object) 
    IL_0015: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_001a: nop 
    IL_001b: ldloc.1 
    IL_001c: ldloca.s i 
    IL_001e: call  instance string [mscorlib]System.Int32::ToString() 
    IL_0023: call  string [mscorlib]System.String::Concat(string, string) 
    IL_0028: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_002d: nop 
    IL_002e: ret 
} // end of method Program::MyDemo 
+0

Buona domanda. Aggiungerei qui: perché non esiste un metodo 'stringa Concat (stringa s, valore T)', che verrà usato dall'operatore '+'. – Dennis

+0

@Dennis quale sarebbe l'uso di quello? –

+0

@Dennis In che modo il compilatore concatena 'T value' con' string s'? Qualunque 'T' può essere concatenato? –

risposta

3

Perché il compilatore dovrebbe farlo? Non può

Se si passa un oggetto (in questo caso uno scatolato int), l'unica possibilità per il compilatore è chiamare string.Concat(object, object). Non è possibile chiamare string.Concat(string, string) poiché non entrambi i parametri sono string e quindi sono conformi al secondo sovraccarico.

Invece, chiama string.Concat(object, object) e fa un ToString interno se applicabile.

Lo sviluppatore ha una conoscenza approfondita di come funziona il metodo string.Concat. Il compilatore non sa che alla fine tutto diventerà un string.

Inoltre, che cosa accadrebbe se uno degli object s è null? ToString non riuscirà con un'eccezione. Questo non ha senso. Basta passare il object e lasciare che il codice gestirlo.

+1

Il compilatore sa che tutti i tipi ereditano l'oggetto in definitiva. L'oggetto contiene il metodo ToString(). Pertanto, quando il compilatore non incontra un argomento String di una funzione che si aspetta String, può chiamare implicitamente ToString(). –

+1

Ma tu come sviluppatore hai una conoscenza approfondita di come funziona il metodo 'string.Concat'. Il compilatore non sa che alla fine tutto diventerà una stringa. –

+2

@JohnDoe - dov'è la linea di demarcazione? Stai dicendo che, per * qualsiasi * insieme di sovraccarichi in cui esistono due sovraccarichi, dove uno accetta un parametro 'stringa' nella stessa posizione in cui l'altro accetta un parametro' object', dovrebbe sempre chiamare 'ToString()' sul oggetto, e quindi il sovraccarico dell'oggetto non è mai richiamabile? –

0

Fonte Riferimento: http://referencesource.microsoft.com/#mscorlib/system/string.cs,8281103e6f23cb5c

rivela che:

public static String Concat(Object arg0) { 
     Contract.Ensures(Contract.Result<String>() != null); 
     Contract.EndContractBlock(); 

     if (arg0 == null) 
     { 
      return String.Empty; 
     } 
     return arg0.ToString(); 
    } 

E 'semplicemente crea una rappresentazione di stringa di quell'oggetto. Quindi qualsiasi oggetto che passi viene convertito in String. String.Empty se è nullo. Penso che questo ci salvi anche dal controllare l'oggetto "null" prima di convertirlo in string.

+1

Abbastanza interessante che esista un metodo per concat_una cosa singola_. – IllidanS4