What is the difference between "x is null" and "x == null"?

In C # 7 we can use

if (x is null) return; 

instead

 if (x == null) return; 

Are there any advantages to using the new method (the previous example) compared to the old one?

Is semantics different?

Is it just a matter of taste? If not, when should I use one on top of the other?

Link: What's New in C # 7.0 .

+157
null c # pattern-matching
Nov 18 '16 at 11:49
source share
2 answers

Update: The Roslyn compiler has been updated to make the behavior of two statements the same when there is no overloaded equality operator. Please see ilr / K4Zwlgdg5gBAygTxAFwKYFsDcAoADsAIwBswBjGUogQxBBgGEYBvbGNmAge06JgFkAjAApOBAFapSyGAA8AlDAC8APlkwwdCMCJEcASC49 AJhHjJ0 UtUylimFp04AvkA == rel = "nofollow noreferrer"> M1 M2 code in the results of the current compiler ( M1 and M2 in the code), which shows what happens when there is no comparison overloaded equality means. Both of them now have better == behavior. If there is an overloaded equality comparator, the code will still be different .

See earlier versions of the Roslyn compiler below for an analysis.




For null there is no difference with what we are used to in C # 6. However, everything becomes interesting when you change null to another constant.

Take this for example:

 Test(1); public void Test(object o) { if (o is 1) Console.WriteLine("a"); else Console.WriteLine("b"); } 

The test gives a . If you compare this to o == (object)1 which you would write normally, this will really make a difference. is takes into account the type on the other side of the comparison. That's cool!

I think the template == null vs. is null constant is just very familiar "by chance", where the syntax of the is operator equals give the same result.




As commented svick , ilr / K4Zwlgdg5gBAygTxAFwKYFsDcAoADsAIwBswBjGUogQxBBgGEYBvbGNmAge06JgFkAjAApOBAFapSyGAA8AlDAC8APlkwwdCMCJEcASC49 AJhHjJ0 UtUylimFp04AvkA == the rel = "noreferrer the nofollow"> is null causes System.Object::Equals(object, object) where == is ceq .

IL for is :

 IL_0000: ldarg.1 // Load argument 1 onto the stack IL_0001: ldnull // Push a null reference on the stack IL_0002: call bool [mscorlib]System.Object::Equals(object, object) // Call method indicated on the stack with arguments IL_0007: ret // Return from method, possibly with a value 

IL for == :

 IL_0000: ldarg.1 // Load argument 1 onto the stack IL_0001: ldnull // Push a null reference on the stack IL_0002: ceq // Push 1 (of type int32) if value1 equals value2, else push 0 IL_0004: ret // Return from method, possibly with a value 

Since we are talking about null , there is no difference, as it only matters in cases . This may change if you overload the equality operator.

+138
Nov 18 '16 at 12:02
source share

In fact, there is a difference in semantics between the two comparisons. The extreme case appears when you compare null with a type that is overloaded with the == operator.

foo is null will use direct link comparisons to determine the result, while foo == null , of course, will run the overloaded operator == if it exists.

In this example, I introduced an β€œerror” in the overloaded == operator, causing it to always throw an exception if the second argument is null :

 void Main() { Foo foo = null; if (foo is null) Console.WriteLine("foo is null"); // This condition is met if (foo == null) Console.WriteLine("foo == null"); // This will throw an exception } public class Foo { public static bool operator ==(Foo foo1, Foo foo2) { if (object.Equals(foo2, null)) throw new Exception("oops"); return object.Equals(foo1, foo2); } // ... } 

The IL code for foo is null uses the ceq statement to perform direct link comparisons:

 IL_0003: ldloc.0 // foo IL_0004: ldnull IL_0005: ceq 

The IL code for foo == null uses a call to the overloaded statement:

 IL_0016: ldloc.0 // foo IL_0017: ldnull IL_0018: call UserQuery+Foo.op_Equality 

So the difference is that if you use == you run the risk of running custom code (which could potentially have unexpected behavior or performance issues).

+35
Jun 12 '18 at 7:37
source share



All Articles