tôi biên dịch các mã C#:
public class MyClass1
{
public MyObject MyObject = new MyObject();
}
public class MyClass2
{
public MyObject MyObject;
public MyClass2()
{
MyObject = new MyObject();
}
}
tôi đã IL lắp ráp:
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
MyClass2:
.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
Đó là prefectly rõ ràng rằng sự khác biệt là chỉ theo thứ tự của cuộc gọi đến constructor lớp cơ sở (hệ thống. Đối tượng ::. Ctor()), Trình khởi tạo MyObject (test.MyObject ::. Ctor()) và trình khởi tạo lớp (kiểm tra lớp stfld test.MyObject.MyClass2 :: MyObject)
Trong trường hợp đầu tiên, MyClass1 khởi như sau:
- MyObject initializer
- lớp initializer (constructor assigment)
- lớp cơ sở khởi tạo (cơ sở lớp constructor)
Nhưng, MyClass2 khởi tạo theo thứ tự đó:
- lớp cơ sở khởi tạo (cơ sở lớp constructor)
- MyObject initializer
- lớp initializer (constructor assigment)
Nguồn
2011-01-28 11:48:38
+1 Ngoài ra, sự hiểu biết của tôi là rằng khởi tạo một thực tế tại tờ khai cho phép trình biên dịch/JITer để làm một số tối ưu hóa mà nó sẽ không làm khác cho một khởi tạo trong constructor. Tôi * tin rằng * Tôi đã đọc điều này trong "Nguyên tắc Thiết kế Khuôn khổ .NET" như là sự biện minh của họ cho việc khởi tạo trường như là một "thực hành tốt nhất", nhưng tôi không chắc chắn nữa. –
@Cody: Không chắc chắn, phải trung thực. Cá nhân tôi sẽ không tính đến điều đó khi viết mã - tôi chỉ gắn bó với cách rõ ràng nhất để thể hiện ý định. –
@Jon Skeet nhầm lẫn: Lớp con không được thừa hưởng Base trong mã – Adeel