nic*_*hev 6 c# reflection nullable
我对以下Nullable
类型的行为感到困惑:
class TestClass {
public int? value = 0;
}
TestClass test = new TestClass();
Run Code Online (Sandbox Code Playgroud)
现在,Nullable.GetUnderlyingType(test.value)
返回基础Nullable
类型,即int
.但是,如果我尝试获得这样的字段类型
FieldInfo field = typeof(TestClass).GetFields(BindingFlags.Instance | BindingFlags.Public)[0];
Run Code Online (Sandbox Code Playgroud)
我援引
Nullable.GetUnderlyingType(field.FieldType).ToString()
Run Code Online (Sandbox Code Playgroud)
它返回一个System.Nullable[System.Int32]
类型.因此,这意味着该方法Nullable.GetUnderlyingType()
具有不同的行为,具体取决于您获取成员类型的方式.为什么会这样?如果我只是使用我test.value
怎么能告诉它Nullable
没有使用反射?
Eri*_*ert 11
smartcaveman的答案是迄今为止最好的答案,它实际上标识了描述此行为的文档部分.
这种行为是不可取的,也是不幸的; 这是由于三种特征相结合的行为,它们本身表现得相当合理.
这三个功能是:
GetType
是一种非虚方法; 它不能被覆盖.这应该是有道理的; 对象无法确定报告的类型.通过使其成为非虚拟,该方法可以保证说实话.
this
传递给声明的非虚方法的值object
必须转换为object
; 因此,对于有价值类型的对象,调用的接收者GetType()
被加框object
.
可以为空的值类型没有盒装形式; 当你打开一个可以为空的int时,你得到一个盒装的int或者你得到一个空引用.您永远不会获得对盒装可空int的有效引用.
每个特性本身都是合理的,但结合起来是不可取的:当你调用GetType
一个有效的可空int时,运行时将nullable int打包到一个盒装的int然后传递给当然报告this
的object.GetType
那个int
.如果该值为null nullable int,则运行时框为null,然后GetType
在空引用上调用并崩溃.这些行为都不可取,但我们坚持使用它们.
可空类型有点奇怪.但是,至少他们的行为有很好的记录.
从MSDN上的C#编程指南,"如何:识别可空类型",请访问http://msdn.microsoft.com/en-us/library/ms366789(VS.80).aspx:
您还可以使用System.Reflection命名空间的类和方法来生成表示Nullable类型的Type对象.但是,如果尝试使用GetType方法或is运算符在运行时从Nullable变量获取类型信息,则结果是一个Type对象,它表示基础类型,而不是Nullable类型本身.
在Nullable类型上调用GetType会导致在将类型隐式转换为Object时执行装箱操作.因此,GetType始终返回表示基础类型的Type对象,而不是Nullable类型.
值得指出的是,标题中的区别是不准确的.类型行为不是基于局部变量或属性,而是基于是通过运行时对象还是通过反射(或使用typeof运算符)来访问类型.你的推理是可以理解的,因为局部变量的类型通常只能通过运行时对象访问,但是它有缺陷,因为如果你在运行时通过属性访问器访问一个可空对象,那么它的行为将等同于一个局部变量.
另外,要明确回答问题的最后一部分:告诉test.value在没有使用反射的情况下可以为空的唯一方法是访问它并获得NullReferenceException(当然,只有当test.value为null时才会发生这种情况)如上所述,在您的示例中,该值不为null,因此无需反射就可以确定此值