.net CIL unbox_任何指令-奇怪的行为

.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检查后尝试将其转换为具体类型。或

isinst指令将调用且不调用unbox.any,如果删除泛型定义并尝试将对象强制转换(isinst)到某个类,则不会调用unbox.any

  • 可能调用unbox.any是因为泛型定义不正确,因此在本例中,unbox.any需要抛出NullReferenceException,因为isinst指令的答案对此强制转换返回null。看见如果您尝试运行此代码,您将看到没有引发异常

  • 更新

    我可以理解unbox_any,因为它使用了object type参数,并在isinst检查后尝试将其转换为具体类型。或许泛型也有影响

    我的问题是,为什么不在unbox.any中抛出一个异常呢?如果我们试图unbox到T的obj为null


    文档中说:“如果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