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

后端 未结 4 1442
悲哀的现实
悲哀的现实 2020-12-19 13:01

When I write this:

ReferenceEquals(x, null)

Visual studio suggests that the

null check can be simplified.

相关标签:
4条回答
  • 2020-12-19 13:34

    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

    0 讨论(0)
  • 2020-12-19 13:37

    I noticed a lot of answers specifying that x == null, x is null, and ReferenceEquals(x, null) are all equivalent - and for most cases this is true. However, there is a case where you CANNOT use x == null as I have documented below:

    Note that the code below assumes you have implemented the Equals method for your class:

    Do NOT do this - the operator == method will be called recursively until a stack overflow occurs:

    public static bool operator ==(MyClass x1, MyClass x2)
    {
       if (x1 == null)
          return x2 == null;
    
       return x1.Equals(x2)
    }
    

    Do this instead:

    public static bool operator ==(MyClass x1, MyClass x2)
    {
       if (x1 is null)
          return x2 is null;
    
       return x1.Equals(x2)
    }
    

    Or

    public static bool operator ==(MyClass x1, MyClass x2)
    {
       if (ReferenceEquals(x1, null))
          return ReferenceEquals(x2, null);
    
       return x1.Equals(x2)
    }
    
    0 讨论(0)
  • 2020-12-19 13:39

    I realize that I'm supre-late to the party and that answers have been given, but I feel the need to summarize a bit since this is a thing I search for every 8-12 months or so and I'd like to have an explanation I can understand (hopefully, if it gets posted)..

    1. ReferenceEquals(a,b)

    This is the tried and tested method to perform a safe reference equality comparison. It basically performs (object)a == (object)b (or something to that effect) and has the advantages that its use is instantly recognizable and it can't be overridden.


    2. a == b

    This method is the one that feels "natural" to most people (since most comparison done throughout C# will be done with this operator).

    Default behaviour on reference types should be correct. However, this can be overloaded, which can lead to unexpected results (imagining a failed implementation of the operator overload).

    Like @mdebeus said, an additional risk (however marginal even for a competent monkey that read a primer on C#) is causing a StackOverflowException. This can appear when overloading == and != and using the operators inside the method itself.


    3. a is b

    OK so this is shiny new sort of sugary thing that we get. Microsoft describes is in this case with:

    The is operator checks if the runtime type of an expression result is compatible with a given type.

    [...]

    The E is T expression returns true if the result of E is non-null and can be converted to type T by a reference conversion, a boxing conversion, or an unboxing conversion; otherwise, it returns false. The is operator doesn't consider user-defined conversions.

    (read a complete description here)

    The short of it is that this will return true if a can be converted through b via boxing, unboxing or covariance. As you would expect, this works very well against null.


    All in all, as a personal note, although is makes things shorter and prettier for null check in equality overloading, I think I'll would still use ReferenceEquals, simply because I'm a control-freak and there is at least a part of how is works that worries me when it comes to cases of covariance.

    0 讨论(0)
  • 2020-12-19 13:57

    Are those really the same?

    Semantically yes (assuming x is not a value type). You're doing a null check which is the same for all reference types.

    Implementation: no. x == null or x is null will be directly implemented as IL instructions but Object.ReferenceEquals(x, null) will be a method call.1

    Also note if the type of x has overridden operator == then x == null may not be equivalent (changing the semantics of null checks in an operator overload is, at best, poor code because no one expects such a semantic change).


    1 Of course the optimiser could recognise this and just output the IL, you'll need to look at the IL to confirm this.

    0 讨论(0)
提交回复
热议问题