我发现如果我运行以下代码行。
int i = 7;
i.GetHashCode(); //where GetHashCode() is the derived
//function from System.Object
没有完成拳击,但是如果我调用i.GetType()
(来自System.Object
的另一个派生函数)代替GetHashCode()
,则需要拳击才能调用GetType()
,为什么不能在没有装箱的情况下直接调用原始类型实例上的GetType()
,而可以在没有装箱的情况下调用GetHashCode()
?
答案 0 :(得分:8)
这里的关键是GetType()
不是虚拟的,不能被覆盖。由于结构实际上是sealed
,因此方法不能覆盖任何 more 而不是结构,因此运行时和编译器可以将已被覆盖的结构方法视为静态调用
如果您编写一个结构(罕见),应该覆盖所有方法,例如ToString()
,Equals()
,GetHashCode()
,正是出于这个原因。如果你不这样做必须装箱。但是,GetType()
无法覆盖,因此需要装箱。
这实际上会导致一些奇怪的边缘情况Nullable<T>
和拳击,因为空Nullable<T>
框到null
,所以:
int i = obj.GetHashCode(); // fine
Type t = obj.GetType(); // boom
答案 1 :(得分:2)
我认为原因是GetHashCode直接在System.Int32上实现,你调用System.Int32 :: GetHashCode()。如果在值类型上调用已知成员函数,则无需使用框。
答案 2 :(得分:1)