![](/img/trans.png)
[英]What is the difference between two ways of using delegates in C# (with new keyword and without)
[英]C# - What's the difference between these two ways of instancing a class property?
基本的C#問題在這里。
在聲明它時或在相關對象的構造函數中創建類屬性/字段的實例有什么區別。 例如:
public class MyClass
{
public MyObject = new MyObject();
}
VS
public class MyClass
{
public MyObject;
public MyCLass()
{
MyObject = new MyObject();
}
}
在調用基本構造函數之前初始化具有初始化程序的字段,而如果初始化程序在主體中,則僅在調用基本構造函數之后執行。
如果基礎構造函數調用虛方法,這可能是相關的 - 但我個人試圖避免這種情況。
示例代碼:
public class Base
{
public Base()
{
Dump();
}
public virtual void Dump() {}
}
public class Child : Base
{
private string x = "Initialized at declaration";
private string y;
public Child()
{
y = "Initialized in constructor";
}
public override void Dump()
{
Console.WriteLine(x); // Prints "Initialized at declaration"
Console.WriteLine(y); // Prints "" as y is still null
}
}
我編譯這些C#代碼:
public class MyClass1
{
public MyObject MyObject = new MyObject();
}
public class MyClass2
{
public MyObject MyObject;
public MyClass2()
{
MyObject = new MyObject();
}
}
我有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
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
完全清楚的是差別僅在於對基類構造函數(System.Object ::。ctor()),MyObject初始化程序(test.MyObject ::。ctor())和類初始化程序(stfld類)的調用順序。 test.MyObject test.MyClass2 :: MyObject)
在第一種情況下,MyClass1初始化如下:
但是,MyClass2按該順序初始化:
您還可以使用在可以初始化靜態變量的任何其他構造函數之前調用的靜態構造函數
public class Bus
{
private static object m_object= null;
// Static constructor:
static Bus()
{
m_object = new object();
System.Console.WriteLine("The static constructor invoked.");
}
public static void Drive()
{
System.Console.WriteLine("The Drive method invoked.");
}
}
class TestBus
{
static void Main()
{
Bus.Drive();
}
}
重要的是要注意(在C#中)對字段的初始化程序賦值將在調用任何基類構造函數之前發生(在這個問題中可以證明VB是否可以強制執行相同的操作)。
這意味着您不能使用初始化程序語法來引用基類的字段(即您無法直接將此VB轉換為C#):
Public Class Base
Protected I As Int32 = 4
End Class
Public Class Class2
Inherits Base
Public J As Int32 = I * 10
End Class
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.