C#空传播 - 哪里魔术发生? [英] C# Null propagation - Where does the magic happen?

查看:185
本文介绍了C#空传播 - 哪里魔术发生?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

空的传播是一个很不错的功能 - 但 ,其中 如何不实际的魔术发生?
哪里 FRM .Close()如果(FRM!= NULL)得到改变,以 frm.Close(); - 它实际上得到改变那种代码在所有

Null propagation is a very nice feature - but where and how does the actual magic happen? Where does frm?.Close() get changed to if(frm != null) frm.Close(); - Does it actually get changed to that kind of code at all?

推荐答案

这是由编译器完成?它不会改变 FRM .Close()如果(FRM!= NULL)frm.Close(); 在重新编写源代码的条款,但它的确实的发射IL字节码检查空

It is done by the compiler. It doesn't change frm?.Close() to if(frm != null) frm.Close(); in terms of re-writing the source code, but it does emit IL bytecode which checks for null.

看看下面的例子:

void Main()
{
    Person p = GetPerson();
    p?.DoIt();
}



编译为:

Compiles to:

IL_0000:  ldarg.0     
IL_0001:  call        UserQuery.GetPerson
IL_0006:  dup         
IL_0007:  brtrue.s    IL_000B
IL_0009:  pop         
IL_000A:  ret         
IL_000B:  call        UserQuery+Person.DoIt
IL_0010:  ret         

这可以解读为:

呼叫 - 呼叫 GetPerson( ) - 存储在堆栈上的结果结果
DUP - 推值压入调用堆栈(再次)

brtrue.s - 弹出堆栈顶部的值。如果这是真的,还是不空(引用类型),然后跳转到 IL_000B

call - Call GetPerson() - store the result on the stack.
dup - Push the value onto the call stack (again)
brtrue.s - Pop the top value of the stack. If it is true, or not-null (reference type), then branch to IL_000B

如果结果是假的(也就是说,对象是的的)结果
弹出 - 弹出堆栈(清除栈,我们没有不再需要)结果
RET 的值 - 返回

If the result is false (that is, the object is null)
pop - Pops the stack (clear out the stack, we no longer need the value of Person)
ret - Returns

如果值是true(也就是说,对象是的不为空的)结果
呼叫 - 呼叫 DOIT()在堆栈的最顶部的值(目前的结果 GetPerson )< BR>
RET - 返回

If the value is true (that is, the object is not null)
call - Call DoIt() on the top-most value of the stack (currently the result of GetPerson).
ret - Returns

手动空检查:

Person p = GetPerson();
if (p != null)
    p.DoIt();

IL_0000:  ldarg.0     
IL_0001:  call        UserQuery.GetPerson
IL_0006:  stloc.0     // p
IL_0007:  ldloc.0     // p
IL_0008:  brfalse.s   IL_0010
IL_000A:  ldloc.0     // p
IL_000B:  callvirt    UserQuery+Person.DoIt
IL_0010:  ret         

请注意,上面是的的一样,但是。检查的有效结果是相同的。

Note that the above is not the same as ?., however the effective outcome of the check is the same.

没有空检查:

void Main()
{
    Person p = GetPerson();
    p.DoIt();
}

IL_0000:  ldarg.0     
IL_0001:  call        UserQuery.GetPerson
IL_0006:  callvirt    UserQuery+Person.DoIt
IL_000B:  ret         

这篇关于C#空传播 - 哪里魔术发生?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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