phi*_*red 7 c# reflection default
假设你有一个类声明,例如:
class MyClass
{
int myInt=7;
int myOtherInt;
}
Run Code Online (Sandbox Code Playgroud)
现在,在通用代码中是否有一种方法,使用反射(或任何其他方法),我可以推断myInt已分配默认值,而myOtherInt则没有?注意用显式默认值初始化和保留默认值的默认值之间的区别(myOtherInt默认初始化为0).
根据我自己的研究,看起来没有办法做到这一点 - 但我想在放弃之前我会问这里.
[编辑]
即使有可空和引用类型,我也希望在那些保留为null的那些和已经显式初始化为null的那些之间进行distingush.这样我可以说具有初始化的字段是"可选的"而其他字段是"强制的".目前我不得不使用属性来做这件事 - 在这种情况下,这会让我感到信息冗余.
cha*_*rit 18
我编译了你的代码并在ILDASM中加载它并得到了它
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.7
IL_0002: stfld int32 dummyCSharp.MyClass::myInt
IL_0007: ldarg.0
IL_0008: call instance void [mscorlib]System.Object::.ctor()
IL_000d: nop
IL_000e: ret
} // end of method MyClass::.ctor
Run Code Online (Sandbox Code Playgroud)
请注意ldc.i4.7
,stfld int32 dummyCSharp.MyClass::myInt
似乎是为myInt字段设置默认值的说明.
因此,这样的赋值实际上被编译为构造函数中的附加赋值语句.
要检测这样的赋值,那么你需要反射来反映MyClass的构造函数方法的IL并查找stfld
(set fields?)命令.
编辑:如果我明确地将一些赋值添加到构造函数中:
class MyClass
{
public int myInt = 7;
public int myOtherInt;
public MyClass()
{
myOtherInt = 8;
}
}
Run Code Online (Sandbox Code Playgroud)
当我在ILDASM中加载它时,我得到了这个:
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 24 (0x18)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.7
IL_0002: stfld int32 dummyCSharp.MyClass::myInt
IL_0007: ldarg.0
IL_0008: call instance void [mscorlib]System.Object::.ctor()
IL_000d: nop
IL_000e: nop
IL_000f: ldarg.0
IL_0010: ldc.i4.8
IL_0011: stfld int32 dummyCSharp.MyClass::myOtherInt
IL_0016: nop
IL_0017: ret
} // end of method MyClass::.ctor
Run Code Online (Sandbox Code Playgroud)
请注意,我添加的myOtherInt的额外分配是在调用Object类的构造函数后添加的.
IL_0008: call instance void [mscorlib]System.Object::.ctor()
Run Code Online (Sandbox Code Playgroud)
所以你有它,
在IL中调用Object类的构造函数之前完成的任何赋值都是默认值赋值.
跟随它的任何内容都是类的实际构造函数代码中的语句.
但是应该进行更广泛的测试.
ps很有趣:-)