这个问题不有关如何初始化支持字段的自动初始化...支持字段
比方说给这个类:
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中,我会假定运行时会处理它。编译器只需要知道规则,即规范说它将被初始化,所以没有警告。没有什么比这更少。 –