3

There is a tweet from Jared Parsons who is c# compiler developer. The tweet claims that we should use "is object" as non null check.

My question is why exactly is that and if I'm getting result from call to service should I run "is object" check instead of "!= null"?

From my understanding and what I can see in Microsoft documentation "is" keyword should be used as type check.

I wasn't able to find "is object" as non null check example anywhere in Microsoft documentation that's why it concerns me if this is really right way to do null check.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
  • 4
    `==` and `!=` can be overloaded in which case the semantics of nullity can be unexpected. Using `is object` or `!(x is null)` guarantee reference comparison. – vc 74 Oct 22 '19 at 13:29
  • vc 74 - can you please provide example on how you can overload == or != ? – Krzysztof Tryc Oct 22 '19 at 13:43
  • The duplicate isn't a good option at all. It doesn't explain why `is object` and `is null` are needed, or what the advantages are. – Panagiotis Kanavos Oct 22 '19 at 13:43
  • Here's the first SO search result I got for operator overloading `==` https://stackoverflow.com/a/25461680/1462295 – BurnsBA Oct 22 '19 at 13:46
  • @BurnsBA the relevant answer though isn't that one. It's the second one which started with `if (b1==null)` demonstrating how easy it is to get this wrong. Assuming someone didn't get clever trying to "fix" nulls – Panagiotis Kanavos Oct 22 '19 at 13:51
  • so I understand that as long as I don't overload "Equals" then there is no difference between "is object" and "!= null" right? – Krzysztof Tryc Oct 22 '19 at 13:52
  • @PanagiotisKanavos er, right, the post I linked was to show operator overloading: `public static bool operator ==(` which op asked about. – BurnsBA Oct 22 '19 at 13:54
  • Maybe the question I asked is not good, maybe I should ask: when you're writing your code do you use "is object" as null check or "!= null" and why? – Krzysztof Tryc Oct 22 '19 at 13:58
  • @ChrisT That's polling for opinions. The question should be objective. –  Oct 22 '19 at 14:00
  • in that case can you please tell me if I'm right in this: "so I understand that as long as I don't overload "Equals"/"==" then there is no difference between "is object" and "!= null" right?" – Krzysztof Tryc Oct 22 '19 at 14:12
  • I think the noted duplicate question's answer, and the comments on that answer, sufficiently answer your question. –  Oct 22 '19 at 14:17
  • @Amy that's not sufficient. The answers to that question were adequate at the time they were written, only about how to properly override those methods. This question is about null checks and the new syntax though. – Panagiotis Kanavos Oct 22 '19 at 14:25
  • 1
    @ChrisT No, this can be very confusing but `Equals` can potentially have a totally different behaviour than `==`, also, `==` is resolved at compile time and `Equals` at runtime. If you really want to check if x is a null reference, the only option before C#7 was to use `object.ReferenceEquals`. With pattern-matching came new options. – vc 74 Oct 22 '19 at 15:57

1 Answers1

2

Jared Parsons is right (obviously), and this isn't a matter of opinion. There are concrete advantages. Use is object or is null when you can. It looks unusual now, but will become far more common in the future.


Up until C# 7, is was only used in type checking. Starting with C# 7 though, it's also used for pattern matching. is null is a constant pattern that matches when the input is exactly null. is object or is string s match on the type.

is null and is object are preferable because someone can overload the Equals and == operators. For example, two boxes with equal sizes can be considered equal. x==null uses the type's equality operator and will only return true if that operator says it's true.

What happens though if there's a mistake, or if someone tried to get clever with equality? And why should we waste CPU to call that operator when we only need to know if that value is null?

One of the answers to the question Operator overloading ==, !=, Equals shows the problem :

The code in operator ==() :

public class BOX
{
    public double Height{get;set;}
    public double Length{get;set;}
    public double Breadth{get;set;}

    public static bool operator == (BOX b1, BOX b2)
    {
        if ((object)b1 == null)
            return (object)b2 == null;

        return b1.Equals(b2);
    }
    ...

Started as :

public static bool operator == (BOX b1, BOX b2)
{
    if (b1 == null)
        return (b2 == null);

    return b1.Equals(b2);
}

Oops - that's infinite recursion! Each of those comparisons ends up calling operator == again. If our own code used :

if (theBoxFromDB == null) ...

We'd get an infinite recursion too. The answerer fixed this by casting to object, thus forcing a comparison using Object.Equals .

We can avoid such unfortunate situations though if we use :

if (theBoxFromDB is null) ...

The equality operator itself can be simplified this way. No extra casts, no calls to ReferenceEquals the way other answers do. :

public static bool operator == (BOX b1, BOX b2)
{
    if (b1 is null)
        return (b2 is null);

    return b1.Equals(b2);
}

Things get more interesting when we start using the full pattern matching syntax. In if(box is null) the only thing we know is that the box is null.

If we use the syntax is T name though, we get a strongly typed, non-null variable :

object box=LoadFromSomewhere();
if(box is Box b)
{
    var volume=box.Height*box.Width*box.Breadth;
}
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
  • Great! Thanks for this, it explains a lot step by step. So I understand that I'm right in assuming that if there is no equality operator overloading then there is no difference between "!= null" and "is object" in any aspects. – Krzysztof Tryc Oct 22 '19 at 14:44
  • @ChrisT but how will you know, unless it's *your* code? – Panagiotis Kanavos Oct 22 '19 at 14:56
  • yes, assuming project is 100% my own code and I'm sure I haven't implemented equality operator overload anywhere then there is no much difference if I use "!= null" or "is object" right? unless there is performance difference, is there any? – Krzysztof Tryc Oct 22 '19 at 15:00
  • @ChrisT not that I know of BUT I don't trust my own code that much, or that I won't introduce a bug in the future - in such cases, future means next Friday just before you leave from work. Better safe than sorry and `is null` whenever possible – Panagiotis Kanavos Oct 22 '19 at 15:03