当我在Microsoft MSDN上发现这篇文章时,我正在研究可空的bool
How to: Identify a Nullable Type (C# Programming Guide)
您可以使用C#typeof运算符创建一个表示Nullable类型的Type对象。
所以我尝试用可空的bool进行检查:
Console.Write(typeof(bool?)); //System.Nullable`1[System.Boolean]
MSDN上的文章说
您还可以使用System.Reflection命名空间的类和方法来生成表示Nullable类型的Type对象。但是,如果您尝试通过使用GetType方法或is运算符在运行时从Nullable变量获取类型信息,则结果是一个Type对象,它表示基础类型,而不是Nullable类型本身。
在Nullable类型上调用GetType会导致在将类型隐式转换为Object时执行装箱操作。 因此,GetType始终返回一个Type对象,该对象表示基础类型,而不是Nullable类型。
如果这是真的,我希望从.GetType()
获得相同的结果,无论我使用可空的bool还是普通的bool。但事实并非如此:
bool a = new bool();
Console.Write(a.GetType()); //Prints System.Boolean
bool? b = new bool?();
Console.Write(b.GetType()); //Exception!
发生的例外情况:
未处理的类型' System.NullReferenceException'发生在BoolTest.exe
附加信息:未将对象引用设置为对象的实例。
但是对象引用设置为对象的实例。可能是造成此错误的原因是什么?
答案 0 :(得分:5)
您的实际问题似乎是:
通过使用默认构造函数(例如
Nullable<T>
)将bool? b = new bool?();
初始化为其默认值,为什么访问b
的成员(例如GetType()
)会抛出{{} 1}?NullReferenceException
不会始终返回值,因此new
不能真正b
吗?
嗯,是的,不是。 null
有点特别。来自C#规范:
4.1.10可空类型
[...]
可空类型T的实例?有两个公共只读属性:
- 类型为bool的HasValue属性
- 类型为T
的Value属性HasValue为true的实例被称为非null。非null实例包含已知值,Value返回该值。 HasValue为false的实例被称为null。 null实例具有未定义的值。尝试读取null实例的值会导致抛出System.InvalidOperationException。
所以是的,Nullable<T>
会返回一个实例:你只能打bool? b = new bool?();
。由于它返回HasValue
,因此您无法对该实例执行其他操作。
然后是下一个相关部分:
4.3.1拳击转化
如果它是空值(HasValue为false),则对可空类型的值进行装箱会产生空引用
MSDN: Boxing Nullable Types (C# Programming Guide)中也解释了这一点:
如果对象为非null,则仅基于可空类型的对象进行装箱。如果HasValue为false,则将对象引用分配为null而不是装箱。
进一步了解规范:
11.3.5装箱和拆箱
当结构类型覆盖从System.Object继承的虚方法(例如Equals,GetHashCode或ToString)时,通过struct类型的实例调用虚方法不会导致发生装箱。
false
未被GetType()
覆盖,因此将发生装箱。当您在结构上调用Nullable<T>
或任何未重写的方法时,在调用该方法之前,结构将被装箱到对象。在空GetType()
的情况下,该装箱操作的结果将是Nullable<T>
。因此例外。
另见Does calling a method on a value type result in boxing in .NET?。
所以,回答你的问题:
(object)null
不 null,它包含b
,Nullable<bool>
表示HasValue
。false
方法,会导致GetType()
结构框被设置为访问基础方法Nullable<bool>
。object.GetType()
。(object)null
,这会引发您遇到的((object)null).GetType()
。如果您实际上正在寻找可以返回任何变量类型的代码,即使是null NullReferenceException
,也可以使用以下内容:
Nullable<T>
然后你可以这样打电话:
Type GetType<T>(T obj)
{
return typeof(T);
}
答案 1 :(得分:4)
您正在Product - Price - SalesDate
ProdA - 10 - 1/1/2016
ProdB - 20 - 1/2/2016
ProdA - 100 - 1/3/2016
ProdB - 20 - 1/4/2016
ProdB - 21 - 1/5/2016
ProdA - 11 - 1/6/2016
参考号上调用GetType
(将Nullable类型装入无值的结果)。
NULL
相当于bool? b = new bool?();
尝试此操作以获得正确的结果:
bool? b = null;
文档意味着如果您在具有值(非空)的bool? b = new bool?(false);
Console.Write(b.GetType()); // System.Boolean
对象上成功调用GetType()
。您获得的基础类型为Nullable
。但是你不能使用System.Boolean
引用调用任何方法,这是应用于任何引用类型的一般规则。
要清除NULL
和= null
之间的等值点,请检查此Fiddle。两者都生成相同的IL:
new bool?()
和
IL_0001: ldloca.s V_0
IL_0003: initobj valuetype [mscorlib]System.Nullable`1<bool>