Diferencia entre usar String.Format y ToString
Hoy cuando he llegado al trabajo me he hecho una de esas preguntas que rápidamente me hacen abrir el VS tirar unas líneas de código y comprobar el IL a ver que ocurre.
La pregunta que me he hecho hoy es:
¿Que diferencia existe entre usar String.Format y ToString?
Para ello he hecho este programita:
1: using System;
2:
3: namespace PruebasBoxing
4: { 5: /// <summary>
6: /// Descripción breve de Test.
7: /// </summary>
8: public class Test
9: { 10: [STAThread]
11: static void Main(string[] args)
12: { 13: double d = 12.45;
14: string formato1 = String.Format("{0:C}", d); 15: string formato2 = d.ToString("C"); 16: }
17: }
18: }
Y el ensamblado lo he abierto con ildasm:
1: .method private hidebysig static void Main(string[] args) cil managed
2: { 3: .entrypoint
4: .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
5: // Code size 41 (0x29)
6: .maxstack 2
7: .locals init ([0] float64 d,
8: [1] string formato1,
9: [2] string formato2)
10: IL_0000: ldc.r8 12.449999999999999
11: IL_0009: stloc.0
12: IL_000a: ldstr "{0:C}" 13: IL_000f: ldloc.0
14: IL_0010: box [mscorlib]System.Double
15: IL_0015: call string [mscorlib]System.String::Format(string,
16: object)
17: IL_001a: stloc.1
18: IL_001b: ldloca.s d
19: IL_001d: ldstr "C"
20: IL_0022: call instance string [mscorlib]System.Double::ToString(string)
21: IL_0027: stloc.2
22: IL_0028: ret
23: } // end of method Test::Main
Si nos fijamos en la línea 14 se está haciendo un boxing del double con lo que se está creando un nuevo tipo referenciado que se pasa a la función String.Format que como vemos recibe un object, y como sabemos este boxing produce una sobrecarga que además hace que el GC sea necesario para limpiar esa referencia cuando deje de utilizarse, cosa que con ToString no ocurre.
Salu2.