Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern matching equal null vs is null

Tags:

c#

c#-7.0

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)) return; // type pattern "int i"
    WriteLine(new string('*', i));
}

Whats the diferrence of o == null and o is null?

like image 726
MuriloKunze Avatar asked Mar 15 '17 15:03

MuriloKunze


People also ask

Should I use is null or == null?

There is also a difference when you try to compare a non-null variable to a null value. When using == , the compiler will issue a Warning, while when using is , the compiler will issue an Error. Most likely, 99% of the time, you want the compiler to shout at you for such a basic mistake. +1 for is null .

Should I use is or == C#?

C#: Why You Should Prefer the is Keyword Over the == Operator. The is keyword has the big advantage that it ignores any operator overloads that are defined on the class of the instance you want to check. When you use the == operator, it could be possible that this operator is overloaded and you get an unexpected result ...

Is null or equal null C#?

ReferenceEquals returns true when the object instances are the same instance. In this case, it returns true when obj is null. Equals is similar to ReferenceEquals when one argument is null .

What pattern matching allows us?

You can use pattern matching to test the shape and values of the data instead of transforming it into a set of objects.


2 Answers

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

like image 105
xanatos Avatar answered Sep 19 '22 08:09

xanatos


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 code
  • o == null will call the overloaded operator==
  • object.Eqauls(o, null) calls that method
  • if you comment the operator== in class C you will see that o == null now produces the same code as o is null
like image 34
enzi Avatar answered Sep 22 '22 08:09

enzi