gotchacsharpCritical
What is the difference between "x is null" and "x == null"?
Viewed 0 times
andbetweenthedifferencewhatnull
Problem
In C# 7, we can use
instead of
Are there any advantages to using the new way (former example) over the old way?
Are the semantics any different?
Is it just a matter of taste? If not, when should I use one over the other?
Reference: What’s New in C# 7.0.
if (x is null) return;instead of
if (x == null) return;Are there any advantages to using the new way (former example) over the old way?
Are the semantics any different?
Is it just a matter of taste? If not, when should I use one over the other?
Reference: What’s New in C# 7.0.
Solution
Update: The Roslyn compiler has been updated to make the behavior of the two operators the same when there is no overloaded equality operator. Please see the code in the current compiler results (
See for older versions of the Roslyn compiler the below analysis.
For
Take this for example:
The test yields
I think the
As svick commented,
IL for
IL for
Since we are talking about
M1 and M2 in the code) that shows what happens when there is no overloaded equality comparer. They both now have the better-performing == behavior. If there is an overloaded equality comparer, the code still differs.See for older versions of the Roslyn compiler the below analysis.
For
null there isn't a difference with what we are used to with C# 6. However, things become 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 yields
a. If you compare that to o == (object)1 what you would have written normally, it does make a lot of difference. is takes into consideration the type on the other side of the comparison. That is cool!I think the
== null vs. is null constant pattern is just something that is very familiar 'by accident', where the syntax of the is operator and the equals operator yield the same result.As svick commented,
is null calls System.Object::Equals(object, object) where == calls ceq.IL for
==: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 valueIL for
is: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 valueSince we are talking about
null, there is no difference since this only makes a difference on instances. This could change when you have overloaded the equality operator.Code Snippets
Test(1);
public void Test(object o)
{
if (o is 1) Console.WriteLine("a");
else Console.WriteLine("b");
}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 valueIL_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 valueContext
Stack Overflow Q#40676426, score: 483
Revisions (0)
No revisions yet.