Differencebetween "X Is Null" and "X == Null"

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

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 (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 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 since this only makes a difference on instances. This could change when you have overloaded the equality operator.

Difference between x = null vs. x IS NULL

This particular case is well-described in Snowflake's documentation:

EQUAL_NULL

IS [ NOT ] DISTINCT FROM

Compares whether two expressions are equal. The function is NULL-safe, meaning it treats NULLs as known values for comparing equality. Note that this is different from the EQUAL comparison operator (=), which treats NULLs as unknown values.

+------+------+--------------------------------+------------------------------------------+----------------------------+--------------------------------------+
| X1_I | X2_I | X1.I IS NOT DISTINCT FROM X2.I | SELECT IF X1.I IS NOT DISTINCT FROM X2.I | X1.I IS DISTINCT FROM X2.I | SELECT IF X1.I IS DISTINCT FROM X2.I |
|------+------+--------------------------------+------------------------------------------+----------------------------+--------------------------------------|
| 1 | 1 | True | Selected | False | Not |
| 1 | 2 | False | Not | True | Selected |
| 1 | NULL | False | Not | True | Selected |
| 2 | 1 | False | Not | True | Selected |
| 2 | 2 | True | Selected | False | Not |
| 2 | NULL | False | Not | True | Selected |
| NULL | 1 | False | Not | True | Selected |
| NULL | 2 | False | Not | True | Selected |
| NULL | NULL | True | Selected | False | Not |
+------+------+--------------------------------+------------------------------------------+----------------------------+--------------------------------------+

Is there a difference between x is null and ReferenceEquals(x, null)?

They mean the same in this case, yes. Most would use x == null though.

I guess ReferenceEquals could be little bit confusing because actually null is a literal that means no reference at all. How can any reference be equal to no reference?

Note that x is null is only allowed with C#7 and it's pattern matching feature. Normally you use is to check if x is a compatible type but null is not a type. So this is a bit confusing as well.

That's why i prefer x == null

Is there any difference between (null != x) and (x != null)

You're going to want to use the second one.

Both do the same exact thing...compare A to B, or compare B to A - both mean the same thing.

It just makes more sense to use x != null because that is more like how we would say this.

You could ask me "Is x not null?" That seems more natural than "Is null not x?" It makes more sense to us.

Is there a difference between !(x is null) and x is object

There is no appreciable difference. They both compile to the same CIL.

Check for yourself here

Note : this is the case even with nullable types as you can see here


From the Standard ECMA-334 C# Language Specification

12.11.11 The is operator

The is operator is used to check if the run-time type of an object is
compatible with a given type. The check is performed at runtime. The
result of the operation E is T, where E is an expression and T is a
type other than dynamic, is a Boolean value indicating whether E is
non-null and can successfully be converted to type T by a reference
conversion, a boxing conversion, an unboxing conversion, a wrapping
conversion, or an unwrapping conversion.

Update

To be completely concise and as pointed out by Alexei Levenkov

!(1 is null) vs. 1 is object shows some difference, the former will not compile due to not being nullable

JavaScript: What is the difference between `if (!x)` and `if (x == null)`?

!x will return true for every "falsy" value (empty string, 0, null, false, undefined, NaN) whereas x == null will only return true if x is null (edit: or apparently undefined (see below)).

Try with x = 0, there is a difference.

You can say that the NOT operator ! converts a value into its opposite boolean equivalent. This is different than actually comparing two values.

In addition, if you compare values with ==, JavaScript does type conversion which can lead to unexpected behavior (like undefined == null). It is better to always use strict comparison === (value and type must be the same) and make use of type conversion only if you really know what you are doing.

Something to read:

  • Data Type Conversion
  • Comparison Operators
  • Logical Operators

Update:

For more information about the non-strict comparison of null and undefined (or the comparison in general), it is worth having a look at the specification. The comparison algorithm is defined there (the comparison is x == y):

  1. If Type(x) is the same as Type(y), then

    (...)
  2. If x is null and y is undefined, return true.
  3. If x is undefined and y is null, return true.
  4. (...)

(...)

Do x as X != null and x is X always return the same result?

Is there any situation where these two if statements will produce different results?

First, note that there are more restrictions on the use of as than of is, so x is X may compile in cases where (x as X) != null may not. For example, as requires that the specified type be a reference type or a nullable type; is works with non-nullable value types as well.

Assume now that both x is X and (x as X) != null are valid expressions. According to §7.10.11 of the C# 4.0 specification, "the operation E as T produces the same result as E is T ? (T)(E) : (T)null". If we plug that latter expression into (x as X) != null, we get

    (x as X) != null
== ((x is X) ? (X)x : null) != null // by the definition of "as"
== (x is X) ? ((X)x != null) : (null != null) // distribute
== (x is X) ? true : false // because (x is X) implies (x != null)
== x is X

This proves that x is X and (x as X) != null are equivalent if both are valid expressions.



Related Topics



Leave a reply



Submit