你可以使用
https://sharplab.io/来测试差异。
??=
和
??
之间的区别非常小,实际上,在代码JIT编译后就消失了。
简而言之:
- 一旦代码编译为汇编语言,它们是相同的。
- 其等效于:
if (text == null){
text = "George";
}
SharpLab 示例
此示例的代码:
public void M1() {
string name = "John";
name ??= "George";
Console.WriteLine(name);
}
public void M2() {
string name = "John";
name = name ?? "George";
Console.WriteLine(name);
}
生成此中间 C# 代码,显示真正的差异:
public void M1()
{
string text = "John";
if (text == null)
{
text = "George";
}
Console.WriteLine(text);
}
public void M2()
{
string text = "John";
text = (text ?? "George");
Console.WriteLine(text);
}
除了复制(dup
)和弹出(pop
)操作外,IL基本上与几乎相同。你可能会认为??
在这方面有些更慢:
IL_0000: nop
IL_0001: ldstr "John"
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: brtrue.s IL_0010
IL_000a: ldstr "George"
IL_000f: stloc.0
IL_0010: ldloc.0
IL_0011: call void [System.Console]System.Console::WriteLine(string)
IL_0016: nop
IL_0017: ret
vs
IL_0000: nop
IL_0001: ldstr "John"
IL_0006: stloc.0
IL_0007: ldloc.0
*** IL_0008: dup
IL_0009: brtrue.s IL_0011
*** IL_000b: pop
IL_000c: ldstr "George"
IL_0011: stloc.0
IL_0012: ldloc.0
IL_0013: call void [System.Console]System.Console::WriteLine(string)
IL_0018: nop
IL_0019: ret
但是发布模式下的程序集是相同的:
C.M1()
L0000: mov ecx, [0x1a58b46c]
L0006: test ecx, ecx
L0008: jnz L0010
L000a: mov ecx, [0x1a58b470]
L0010: call System.Console.WriteLine(System.String)
L0015: ret
C.M2()
L0000: mov ecx, [0x1a58b46c]
L0006: test ecx, ecx
L0008: jnz L0010
L000a: mov ecx, [0x1a58b470]
L0010: call System.Console.WriteLine(System.String)
L0015: ret
if (name != null) {
应该改为if (name == null) {
。 - TheMisir