Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are these two lines the same, '? ... :' vs '??'?

Tags:

c#

Is there a difference between these two lines?

MyName = (s.MyName == null) ? string.Empty : s.MyName 

or

MyName = s.MyName ?? string.Empty 
like image 991
user1307149 Avatar asked Jan 10 '14 19:01

user1307149


People also ask

How do you know if two lines are the same?

To see whether or not two lines are parallel, we must compare their slopes. Two lines are parallel if and only if their slopes are equal. The line 2x – 3y = 4 is in standard form. In general, a line in the form Ax + By = C has a slope of –A/B; therefore, the slope of line q must be –2/–3 = 2/3.

What are two lines that are the same?

Parallel Lines: Definition: We say that two lines (on the same plane) are parallel to each other if they never intersect each other, ragardless of how far they are extended on either side. Pictorially, parallel lines run along each other like the tracks of a train.

Are two lines parallel if they are the same line?

If two lines are parallel to the same line, then they are parallel to each other.

Are these lines parallel or perpendicular?

Parallel lines are the lines that never intersect and perpendicular lines are the lines that intersect at 90 degrees.


2 Answers

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.

like image 110
Steven Wexler Avatar answered Oct 13 '22 06:10

Steven Wexler


If the property is more than a simple getter, you might be executing a function twice in the non-null case for the first one.

If the property is in a stateful object, then the second call to the property might return a different result:

class MyClass {     private IEnumerator<string> _next = Next();      public MyClass()     {         this._next.MoveNext();     }      public string MyName     {         get         {             var n = this._next.Current;             this._next.MoveNext();             return n;         }     }       public static IEnumerator<string> Next()     {         yield return "foo";         yield return "bar";     } } 

Also, in the non-string case, the class might overload == to do something different than the ternary operator. I don't believe that the ternary operator can be overloaded.

like image 24
Dan Gallagher Avatar answered Oct 13 '22 05:10

Dan Gallagher