這個問題不有關如何初始化支持字段的自動初始化...支持字段
比方說給這個類:
public class Test
{
public int PropertyA { get; set; }
public int PropertyB { get; set; }
private int _propertyC;
public int PropertyC { get { return _propertyC; } set { _propertyC = value; } }
}
有,無論是自動定義的許多屬性並明確實施。
讓我們仔細看看如何編譯PropertyA
(64位調試)。的MSIL輸出是這樣的:
.field private int32 'k__BackingField' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (01 00 00 00) .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = (01 00 00 00 00 00 00 00) .property instance int32 PropertyA() { .get instance int32 TestCode.Test::get_PropertyA() .set instance void TestCode.Test::set_PropertyA(int32) } // end of property Test::PropertyA .method public hidebysig specialname instance int32 get_PropertyA() cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (01 00 00 00) // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: ldfld int32 TestCode.Test::'k__BackingField' IL_0006: ret } // end of method Test::get_PropertyA .method public hidebysig specialname instance void set_PropertyA(int32 'value') cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (01 00 00 00) // Code size 8 (0x8) .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: stfld int32 TestCode.Test::'k__BackingField' IL_0007: ret } // end of method Test::set_PropertyA
這是非常基本的,它定義了支持字段,屬性,然後將get_
和_set
方法爲該屬性,負載或設置支持字段。
我沒有得到什麼(我認爲是理所當然的,直至現在),是,這是一個完全合法的構造函數:
public Test()
{
Debug.WriteLine($"{PropertyA.ToString()}");
Debug.WriteLine($"{_propertyC.ToString()}");
}
雖然這顯然是一個編譯器錯誤:
public Test()
{
int i;
Debug.WriteLine($"{i.ToString()}");
}
其中,如預期的那樣,給CS0165「使用未分配的本地變量'i'」。在爲此進行一些研究並挖掘ECMA Spec和Microsoft C# spec(5.0是最後一份正式文檔,6.0似乎鬆散地分佈在Roslyn項目中),並且我找不到與字段初始化相關的任何內容。
我確實發現this reference from VS2003逃避到類字段被初始化爲default
類型的值,但它表明這是語言的一部分,而不是運行時。
所以問題是......運行時是否執行字段的初始化,或者我是否正在初始化這些值的編譯器中丟失MSIL中的某些內容?我假設編譯器這樣做,否則我會期望在這兩個示例構造函數中相同的CS0165。
所以你基本上想知道爲什麼你可以調用一個未分配的屬性,但不是一個未分配的本地變量? –
我明白*爲什麼*但我不明白*如何*。初始化發生在哪裏? –
規範的第17.4.4節中沒有對此進行描述嗎? 「字段的初始值,無論是靜態字段還是實例字段,都是字段類型的缺省值(第12.2節)。在默認初始化發生之前,無法觀察字段的值,並且一個字段從來沒有「未初始化」?如果它不在MSIL中,我會假定運行時會處理它。編譯器只需要知道規則,即規範說它將被初始化,所以沒有警告。沒有什麼比這更少。 –