Does using the null-conditional operator duplicate null checks? For example
var x = instance?.Property1;
var y = instance?.Property2;
Does that get compiled into this:
if (instance != null)
{
var x = instance.Property1;
var y = instance.Property2;
}
Or this?
if (instance != null)
{
var x = instance.Property1;
}
if (instance != null)
{
var y = instance.Property2;
}
If the former, does it make a difference if there is other code in between both lines? In other words, how smart is the compiler/optimizer?
The compiler appears to be quite ignorant of this.
The code:
var x = instance?.Property1;
var y = instance?.Property2;
...compiles as non-optimized to:
IL_0000: nop
IL_0001: newobj UserQuery+Class..ctor
IL_0006: stloc.0 // instance
IL_0007: ldloc.0 // instance
IL_0008: brtrue.s IL_000D
IL_000A: ldnull
IL_000B: br.s IL_0013
IL_000D: ldloc.0 // instance
IL_000E: ldfld UserQuery+Class.Property1
IL_0013: stloc.1 // x
IL_0014: ldloc.0 // instance
IL_0015: brtrue.s IL_001A
IL_0017: ldnull
IL_0018: br.s IL_0020
IL_001A: ldloc.0 // instance
IL_001B: ldfld UserQuery+Class.Property2
IL_0020: stloc.2 // y
IL_0021: ret
Class..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: nop
IL_0007: ret
...and to optimized as:
IL_0000: newobj UserQuery+Class..ctor
IL_0005: dup
IL_0006: dup
IL_0007: brtrue.s IL_000C
IL_0009: pop
IL_000A: br.s IL_0012
IL_000C: ldfld UserQuery+Class.Property1
IL_0011: pop
IL_0012: dup
IL_0013: brtrue.s IL_0017
IL_0015: pop
IL_0016: ret
IL_0017: ldfld UserQuery+Class.Property2
IL_001C: pop
IL_001D: ret
Class..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: ret
Both clearly with two branch checks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With