如果是新的c#6“?”,则使用call而不是callvirt空检查 [英] call instead of callvirt in case of the new c# 6 "?" null check

查看:89
本文介绍了如果是新的c#6“?”,则使用call而不是callvirt空检查的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出两种方法:

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

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

为什么M1 IL代码使用 callvirt

Why the M1 IL code use 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使用 call

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且类似

I just can guess that it because in M2 we know that p isn't null and its like

new MyClass().MyMethod();

是真的吗?

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

If it is, what if p will be null in other thread?

推荐答案

我认为现在已经很清楚了,

I think it's clearly now,


这是在触发事件之前检查null的一种简单且线程安全的方法。之所以具有线程安全性,是因为该功能只评估左侧一次,并将其保留在一个临时变量中。 MSDN

因此在此处使用 call 指令是安全的。

So it is safe to use call instruction here.

我写了一个博客文章关于 call callvirt 之间的区别以及C#为什么生成 callvirt

I wrote a blog post about the differences between call and callvirt and why C# generate callvirt

感谢 Dan里昂(用于MSDN链接)。

Thanks Dan Lyons for the MSDN link.

这篇关于如果是新的c#6“?”,则使用call而不是callvirt空检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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