Dud*_*eti 5 .net clr il cil nullreferenceexception
.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
Run Code Online (Sandbox Code Playgroud)
相同的C#代码是:
public static void Test<T>(object o) where T : class
{
T t = o as T;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
为什么unbox.any被称为?如果你这样做
var a = father as child
Run Code Online (Sandbox Code Playgroud)
isinst intruction将调用而不是unbox.any,如果我将删除泛型定义并且我将尝试将(isinst)对象强制转换为某个类,则不会调用unbox.any.
也许因为泛型定义而调用unbox.any,所以在这种情况下unbox.any需要抛出NullReferenceException,因为isinst指令的答案为此转换返回null.请参阅unbox_any.如果您尝试运行此代码,您将看到没有抛出任何异常.
更新
我可以理解unbox_any因为对象类型参数,它尝试在isinst检查后将其强制转换为具体类型.也许仿制药也会影响.
我的问题是,为什么不在unbox.any中抛出异常,如果我们尝试unbox到T的obj是null?
文档说:"如果obj是一个空引用,则抛出NullReferenceException."
拆箱是为了让验证者开心。验证器在知道类型参数 T 始终是引用类型方面并不是特别聪明,因此 C# 编译器会发出这些不必要的拆箱。
如果您搜索 Unbox_any 和 IsVerifierReference 的 Roslyn 源代码,您会发现这种情况发生在代码生成器的很多地方。
抖动会在生成代码时知道类型参数是否是引用,并且应该生成合适的代码,而不管看似不必要的指令。
归档时间: |
|
查看次数: |
258 次 |
最近记录: |