为什么在原始类型实例上调用Object类的某些函数需要装箱?

wah*_*eed 10 .net c# .net-internals

我发现如果我运行以下代码行.

int i = 7;
i.GetHashCode(); //where GetHashCode() is the derived
                 //function from System.Object
Run Code Online (Sandbox Code Playgroud)

没有拳击已经完成,但如果我调用i.GetType()(另一个派生函数System.Object)代替GetHashCode(),拳击将需要调用GetType(),为什么它不可能直接调用GetType()原始类型实例,没有拳击,而它可以调用GetHashCode()没有拳击?

Mar*_*ell 8

这里的关键GetType()是不是虚拟的,不能被覆盖.由于结构是有效的sealed,方法不能被重写任何比结构,使运行时和编译器可以把结构的方法已被重写为静态调用.

如果你写一个struct(罕见),你应该覆盖所有喜欢的方法ToString(),Equals(),GetHashCode()正是这种原因.如果你不这样做必须装箱.但是,GetType() 不能被覆盖,因此需要拳击.

这实际上导致了一些奇怪的边缘例Nullable<T>和拳击,因为一个空Nullable<T>null,那么:

int i = obj.GetHashCode(); // fine
Type t = obj.GetType(); // boom
Run Code Online (Sandbox Code Playgroud)