CIL unbox_any指令-奇怪的行为 [英] CIL unbox_any instruction - strange behavior

查看:105
本文介绍了CIL unbox_any指令-奇怪的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

.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

相等的C#代码为:

public static void Test<T>(object o) where T : class
{
    T t = o as T;
}

我的问题是:


  1. 为什么调用unbox.any?

  1. Why unbox.any been called? if you just do

 var a = father as child 

isinst指令将调用并且没有unbox.any,并且如果我将删除泛型定义并尝试将对象强制转换(isinst)为某个类,则不会取消包装.any将被调用。

isinst intruction will call and no unbox.any, and If i'll remove the generic definition and i'll try to cast (isinst) the object to some class, no unbox.any will be called.

也许因为未定义,所以调用了unbox.any,因为在这种情况下,unbox.any需要抛出NullReferenceException,因为isinst指令的答案为此转换返回null。请参阅 unbox_any 。而且,如果您尝试运行此代码,您将看到没有引发异常。

Maybe unbox.any been called because the generic definition, so in this case the unbox.any need to throw a NullReferenceException because the answer of isinst instruction return null for this casting. see unbox_any. And if you try to run this code you will see that no exception has thrown.

更新

我可以理解unbox_any因为对象类型参数,并在isinst检查之后尝试将其转换为具体类型。

I can understand the unbox_any becuase the object type parameter and it try to cast it to concrete type after the isinst check. Maybe the generics influence also.

我的问题是,为什么不尝试在unbox.any中抛出异常,如果我们尝试将T拆箱的obj为null?

My question is, why not thrown an exception in unbox.any if the the obj we try to unbox to T is null?

文档说:如果obj为空引用,则抛出NullReferenceException。

The documentation say: "NullReferenceException is thrown if obj is a null reference."

推荐答案

取消选中框是为了使验证者满意。对于知道类型参数T始终是引用类型的情况,验证程序并不是特别聪明,因此C#编译器会发出这些原本不必要的取消框。

The unbox is to keep the verifier happy. The verifier is not particularly smart about knowing that a type parameter T is always going to be a reference type, and so the C# compiler emits these otherwise unnecessary unboxes.

在Roslyn源代码中搜索Unbox_any和IsVerifierReference,您会发现这发生在代码生成器周围的很多地方。

If you do a search of the Roslyn source code for Unbox_any and IsVerifierReference you'll see that this happens in quite a few places around the code generator.

生成时抖动会知道该代码,无论type参数是否为引用,并且无论看似不必要的指令如何,都应生成体面的代码。

The jitter will know when generating the code whether the type parameter is a reference or not and should generate decent code regardless of the seemingly unnecessary instruction.

这篇关于CIL unbox_any指令-奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆