compilo éstos código C#:
public class MyClass1
{
public MyObject MyObject = new MyObject();
}
public class MyClass2
{
public MyObject MyObject;
public MyClass2()
{
MyObject = new MyObject();
}
}
que tiene ensamblaje IL:
MyClass1:
.class public auto ansi beforefieldinit test.MyClass1
extends [mscorlib]System.Object
{
.field public class test.MyObject MyObject
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// code size: 19 (0x13)
.maxstack 8
IL_0000: ldarg.0
IL_0001: newobj instance void test.MyObject::.ctor()
IL_0006: stfld class test.MyObject test.MyClass1::MyObject
IL_000b: ldarg.0
IL_000c: call instance void [mscorlib]System.Object::.ctor()
IL_0011: nop
IL_0012: ret
} // end of method MyClass1::.ctor
} // end of class test.MyClass1
miclase2:
.class public auto ansi beforefieldinit test.MyClass2
extends [mscorlib]System.Object
{
.field public class test.MyObject MyObject
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// code size: 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: nop
IL_0008: ldarg.0
IL_0009: newobj instance void test.MyObject::.ctor()
IL_000e: stfld class test.MyObject test.MyClass2::MyObject
IL_0013: nop
IL_0014: ret
} // end of method MyClass2::.ctor
} // end of class test.MyClass2
Es prefectamenta claro que la diferencia es sólo en el orden de llamada a la (Sistema constructor de la clase base. Object ::. Ctor()), inicializador MyObject (test.MyObject ::. Ctor()) y el inicializador de clase (stfld class test.MyObject test.Miclase2 :: MyObject)
En el primer caso, MyClass1 inicializa como sigue:
- MyObject inicializador
- clase inicializador (assigment constructor)
- inicializador de la clase base (clase constructor base)
Pero, MyClass2 se inicializa por ese orden:
- clase base inicializador (constructor de la clase base)
- MiObjeto inicializador
- inicializador de la clase (assigment constructor)
+1 Además, mi opinión es que la inicialización de un campo en la declaración permite al compilador/a JITer hacer algunas optimizaciones que de otro modo no haría para una inicialización en el constructor. Creo que * lo leí en las "Pautas de diseño de .NET Framework" como su justificación para preferir la inicialización de campo como una "mejor práctica", pero ya no estoy seguro. –
@Cody: No estoy seguro, para ser sincero. Yo personalmente no tomaría esto en cuenta al escribir el código; me limitaría a seguir la forma más clara de expresar intenciones. –
@Jon Error de Skeet: Clase infantil no heredada de Base en el código – Adeel