gpt4 book ai didi

c# - 去除unbox_any的抖动逻辑

转载 作者:太空狗 更新时间:2023-10-29 23:37:43 25 4
gpt4 key购买 nike

我正在调查此 C# 代码的执行情况:

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

等效的 IL 代码是:

.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

基于这个答案(unnecessary unbox_any),任何人都可以向我解释 Jitter 在这里执行的确切逻辑吗?在这种特定情况下,Jitter 究竟是如何决定忽略“unbox_any”指令的(理论上,根据 msdn ,当 isinst 指令产生 null 时应该抛出 NullReferenceException,但这在实践中不会发生!)

更新

根据 usr answer 和 Hans comment,如果 obj 是引用类型,castclass 将被调用,因此,没有 NRE .

但是下面的情况呢?

static void Test<T>(object o) where T : new()
{
var nullable = o as int?;
if (nullable != null)
//do something
}

Test<int?>(null);

以及等效的 IL 代码(部分):

IL_0001:  ldarg.0
IL_0002: isinst valuetype [mscorlib]System.Nullable`1<int32>
IL_0007: unbox.any valuetype [mscorlib]System.Nullable`1<int32>
IL_000c: stloc.0
IL_000d: ldloca.s nullable
IL_000f: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0014: stloc.1
IL_0015: ldloc.1
IL_0016: brfalse.s IL_0024

在这种情况下它是值类型,那么为什么不抛出 NRE?

最佳答案

When applied to a reference type, the unbox.any instruction has the same effect as castclass typeTok.

T 被限制为引用类型。在这种情况下,该指令不会抛出 NRE。 JIT 不会“忽略”它,而是按指定执行它。不允许 JIT 忽略指令。

文档有声明

NullReferenceException is thrown if obj is a null reference.

这是一种误导,因为它只适用于值类型。我引用的第一个声明是明确的。

关于c# - 去除unbox_any的抖动逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34382683/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com