gpt4 book ai didi

c# - 在新的 c# 6 "?"空检查的情况下调用而不是 callvirt

转载 作者:可可西里 更新时间:2023-11-01 08:23:11 26 4
gpt4 key购买 nike

给定两种方法:

    static void M1(Person p)
{
if (p != null)
{
var p1 = p.Name;
}
}

static void M2(Person p)
{
var p1 = p?.Name;
}

为什么 M1 IL 代码使用 callvirt:

IL_0007:  brfalse.s  IL_0012
IL_0009: nop
IL_000a: ldarg.0
IL_000b: callvirt instance string ConsoleApplication4.Person::get_Name()

M2 IL 使用调用:

brtrue.s   IL_0007
IL_0004: ldnull
IL_0005: br.s IL_000d
IL_0007: ldarg.0
IL_0008: call instance string ConsoleApplication4.Person::get_Name()

我只能猜到,因为在 M2 中我们知道 p 不是 null 之类的

new MyClass().MyMethod();

这是真的吗?

如果是,如果 p 在其他线程中为 null 怎么办?

最佳答案

M1 中的callvirtstandard C# code generation .它提供了永远不能用空引用调用实例方法的语言保证。换句话说,它确保 p != null 并在它为 null 时生成 NullReferenceException。您的明确测试不会改变这一点。

这个保证非常好,如果 this 为 null,则调试 NRE 会变得很棘手。相反,在调用点诊断错误要容易得多,调试器可以快速向您显示 p 是麻烦制造者。

当然callvirt不是免费的,虽然成本很低,运行时多一条处理器指令。因此,如果它可以call 代替,那么代码将快半纳秒,给或取。它实际上可以与 elvis 运算符一起使用,因为它已经确保引用不为空,因此 C# 6 编译器利用了这一点并生成调用而不是 callvirt。

关于c# - 在新的 c# 6 "?"空检查的情况下调用而不是 callvirt,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34535000/

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