Are these two lines the same, '? ... :' vs '??'?
c#
Solution
UPDATE: I wrote a blog post that discusses this topic in more depth. http://www.codeducky.org/properties-fields-and-methods-oh-my/
Generally they will return the same result. However, there are a few cases where you will experience noticeable differences when `MyName` is a property because the `MyName` getter will be executed twice in the first example and only once in the second example.
For example, you may experience performance differences from executing `MyName` twice:
string MyName
{
get
{
Thread.Sleep(10000);
return "HELLO";
}
}
Or you may get different results from executing `MyName` twice if `MyName` is stateful:
private bool _MyNameHasBeenRead = false;
string MyName
{
get
{
if(_MyNameHasBeenRead)
throw new Exception("Can't read MyName twice");
_MyNameHasBeenRead = true;
Thread.Sleep(10000);
return "HELLO";
}
}
Or you may get different results from executing `MyName` twice if `MyName` can be changed on a different thread:
void ChangeMyNameAsync()
{
//MyName set to null in another thread which makes it
//possible for the first example to return null
Task.Run(() => this.MyName = null);
}
string MyName { get; set; }
Here's how the actual code is compiled. First the piece with the ternary expression:
IL_0007: ldloc.0 // s
IL_0008: callvirt s.get_MyName <-- first call
IL_000D: brfalse.s IL_0017
IL_000F: ldloc.0 // s
IL_0010: callvirt s.get_MyName <-- second call
IL_0015: br.s IL_001C
IL_0017: ldsfld System.String.Empty
IL_001C: call set_MyName
and here is the piece with the null-coalescing operator:
IL_0007: ldloc.0 // s
IL_0008: callvirt s.get_MyName <-- only call
IL_000D: dup
IL_000E: brtrue.s IL_0016
IL_0010: pop
IL_0011: ldsfld System.String.Empty
IL_0016: call s.set_MyName
As you can see the compiled code for the ternary operator will make two calls to get the property value, whereas the null-coalescing operator will only do 1.
Problem
Is there a difference between these two lines? ``` MyName = (s.MyName == null) ? string.Empty : s.MyName ``` or ``` MyName = s.MyName ?? string.Empty ```