call instead of callvirt in case of the new c# 6 “?” null check

前端 未结 3 1674
后悔当初
后悔当初 2021-02-19 06:17

Given the two methods:

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

    static void M2(Perso         


        
3条回答
  •  离开以前
    2021-02-19 06:54

    The callvirt in M1 is standard C# code generation. It provides the language guarantee that an instance method can never be called with a null reference. In other words, it ensures that p != null and generates NullReferenceException if it is null. Your explicit test does not change that.

    This guarantee is pretty nice, debugging NRE gets pretty hairy if it is this that is null. Much easier to diagnose the mishap at the call-site instead, the debugger can quickly show you that it is p that is the troublemaker.

    But of course callvirt is not for free, although the cost is very low, one extra processor instruction at runtime. So if it can be substituted by call then the code will be faster by half a nanosecond, give or take. It in fact can with the elvis operator since it already ensures that the reference isn't null so the C# 6 compiler took advantage of that and generates call instead of callvirt.

提交回复
热议问题