可空类型究竟何时会引发异常?

考虑以下代码:


int? x = null;

Console.Write ("Hashcode: ");

Console.WriteLine(x.GetHashCode());

Console.Write("Type: ");

Console.WriteLine(x.GetType());

执行时,它会写为Hashcode为0,但NullReferenceException尝试确定的类型失败x。我知道在可空类型上调用的方法实际上是在基础值上调用的,因此我希望程序在期间会失败x.GetHashCode()。


那么,这两种方法之间的根本区别是什么,为什么它们中的第一种不会失败?


烙印99
浏览 153回答 3
3回答

白衣染霜花

这是因为int? x = null;本质上会创建一个System.Nullable<int>带有“内部”null值(您可以通过.HasVaueProperty对其进行检查)的value类型的实例。当GetHashCode被调用时,倍率Nullable<int>.GetHashCode是方法候选(因为该方法是虚拟的),现在我们有一个实例Nullable<int>,并执行它的实例方法,完善。调用时GetType,该方法是非虚拟的,因此根据文档将的实例Nullable<int>装箱至System.Object第一个,装箱的值为,因此为。nullNullReferenceException

慕桂英546537

为了弄清陈百强的正确答案:Nullable<T>是一个值类型。值类型由布尔值(表示无效)(布尔值表示null)和T(值)组成。与所有其他值类型不同,可为空的类型不会对boxed进行装箱Nullable<T>。它们装箱到装箱T的引用或空引用。由值类型S实现的方法的实现就好像它具有不可见的ref S参数一样。那this就是通过的方式。由引用类型C实现的方法的实现方式就好像存在一个不可见的C参数一样。那this就是通过的方式。然后,有趣的情况是在引用基类中定义的虚拟方法,并被从基类继承的结构覆盖。现在,您有足够的信息来推断会发生什么。GetHashCode是虚拟的,并且被覆盖,Nullable<T>因此当您调用它时,就好像是存在一个不可见的ref Nullable<T>参数一样调用它this。没有拳击发生。GetType不是虚拟的,因此不能被覆盖,并且在上定义object。因此,它期望objectfor&nbsp;this,当Nullable<T>在接收器上调用时,接收者必须装箱,因此可以装箱为null,因此可以抛出。如果您致电,((object)x).GetHashCode()您将看到一个异常。
打开App,查看更多内容
随时随地看视频慕课网APP