From Microsoft new-features-in-c-7-0:
public void PrintStars(object o)
{
if (o is null) return; // constant pattern \"null\"
if (!(o is int i)) r
The differences between "is" and == is "is" special that it act as == if you compare to value and act as typeof(type) when you compare type of object to type.
Since the answer of @xanatos is outdated (but that is only mentioned at the very end) I'm writing a new one, because I wanted to know this as well and researched it.
In short: if you don't overload the ==
operator, then o == null
and o is null
are the same.
If you do overload the ==
operator, then o == null
will call that, but o is null
won't.
o is null
always does the same as ReferenceEquals(o, null)
, i.e. it only checks if the value is null, it doesn't call any operators or Equals
methods.
Longer answer: here is a SharpLab sample that showcases the various ways to check for null.
If you view the result in IL form you see that:
is null
and ReferenceEquals
result in the same codeo == null
will call the overloaded operator==
object.Eqauls(o, null)
calls that methodoperator==
in class C
you will see that o == null
now produces the same code as o is null
The o is null
is translated to object.Equals(null, o)
(you can see it here).
The object.Equals
code is written as:
public static bool Equals(Object objA, Object objB)
{
if (objA == objB)
{
return true;
}
if (objA == null || objB == null)
{
return false;
}
return objA.Equals(objB);
}
so in the end there will be a o == null
(the first if
). Note that System.Object
doesn't define the operator==
, so the one used is the one for reference types that is reference equality.
Theorically, by watching the called code, one could think that o == null
(with o
a System.Object
) should be faster than o is null
(less operations)... But who knows? :-)
The end result is that, through two different routes, o is null
and o == null
(with o
a System.Object
) return the same result.
By looking we can even see that o == null
is the same as object.ReferenceEquals(o, null)
(with o
a System.Object
) :-).
the interesting question should be, why doesn't the C# compiler translates the x is null
to object.ReferenceEquals(x, null)
?. Note that, thanks to how the boxing of nullable types is done, it would work even for:
int? a = null;
if (a is null) { /* */ }
changes to the compiler made this response invalid... If you click on the "here" link you can see it