.net CIL unbox_任何指令-奇怪的行为
isinst指令将调用且不调用unbox.any,如果删除泛型定义并尝试将对象强制转换(isinst)到某个类,则不会调用unbox.any.net CIL unbox_任何指令-奇怪的行为,.net,clr,nullreferenceexception,cil,il,.net,Clr,Nullreferenceexception,Cil,Il,isinst指令将调用且不调用unbox.any,如果删除泛型定义并尝试将对象强制转换(isinst)到某个类,则不会调用unbox.any 可能调用unbox.any是因为泛型定义不正确,因此在本例中,unbox.any需要抛出NullReferenceException,因为isinst指令的答案对此强制转换返回null。看见如果您尝试运行此代码,您将看到没有引发异常 更新 我可以理解unbox_any,因为它使用了object type参数,并在isinst检查后尝试将其转换为具体类型。或
文档中说:“如果obj是空引用,则抛出NullReferenceException。”取消绑定是为了让验证器满意。验证器在知道类型参数T始终是引用类型方面不是特别聪明,因此C#编译器会发出这些不必要的unbox 如果您在Roslyn源代码中搜索Unbox_any和IsVerifierReference,您将看到在代码生成器的许多地方都会发生这种情况
在生成代码时,抖动将知道类型参数是否为引用,并且应该生成适当的代码,而不考虑看似不必要的指令。您能详细说明什么是奇怪的吗?对我来说这是有道理的。在第(2)点中,您也没有问任何问题。@usr First,,我想验证调用unbox_any的原因。给他们两个都打电话有什么意义?(isinst和unbox_any)其次,更重要的是,如果传递给unbox_any的obj为空,为什么没有引发异常?如果有人对此感兴趣,我建议查看完整图片
.method public static void Test<class T>(object A_0) cil managed
{
// Code size 13 (0xd)
.maxstack 1
.locals init (!!T V_0)
IL_0000: ldarg.0
IL_0001: isinst !!T
IL_0006: unbox.any !!T
IL_000b: stloc.0
IL_000c: ret
} // end of method DemoType::Test
public static void Test<T>(object o) where T : class
{
T t = o as T;
}
var a = father as child