Question

When I have to implement equality comparers for

public class SampleClass
{
    public int Prop { get; set; }
}

Should I make

null == new SampleClass() 

and

new SampleClass() == null

and

new SampleClass().Equals(null)

false?

And what about

new SampleClass() != null

Should it be also false?

UPDATE People are questioning the reasoning behind this question. It's supposed that != and == be always opposites. But if I implement the methods so all those comparisons above results in false, there will be a case where the == and != operators will result the same result. So it's a dilemma whether != should return true or false.

Was it helpful?

Solution

All the equality comparions with null from your example should definitely be false. The last one is also very important however:

new SampleClass() != null

This must definitely evaluate to true, because this is a common way to check if a reference variable has been initialized. If it were to evaluate to false, it might unintentionally reassign the variable all over the place, because C# developers expect a certain kind of behavior from there operators. Another example:

SampleClass myVar = new SampleClass();

// Various stuff happening here, possibly setting myVar to null

if (myVar != null)
{
    // Programmer go "WTFBBQ?" when he finds this doesn't get executed
    myVar.DoStuff();
}

Confused, the programmer changes this to:

if (myVar == null)
{
    myVar = new SampleClass();
}

myVar.DoStuff(); // null reference exception, huh?

OTHER TIPS

Is it even a question? No, null should never be equal to an object.

Edit: And thus by extension, new SampleClass() != null should be true. null isn't like NaN; it's pretty well-defined.

As well as what has been stated, note that:

The predefined reference type equality operators are:

bool operator ==(object x, object y);
bool operator !=(object x, object y);

So....

SampleClass a = null;
SampleClass b = null;
  • a == b is true
  • a != b is false

Read what the .NET framework designers said on the question:

Why don't nullable relational operators return “bool?” instead of “bool“?

For more info, read:

I'm not sure I fully understand your question, but null is (by definition) not a value. As such,

null == new SampleClass()

doesn't really make any sense (and, really, none of the other comparisons do).

Can you rephrase your question?

As others have said, null can never be equal to anything else including null. This is because null isn't a value, rather it is a lack of a value.

For your specific question, it seems like you are trying to instantiate an object that has not yet been initialized and you want to determine whether or not that object has been initialized. My suggestion would be to include a property that indicates whether or not the object has been initialized.

Null should never compare as equal to a non-null reference. By extension, your != should return true as it is the opposite of the equality.

If you have an instance of an object, you do not have null and all equality comparers should respect this.

I think this is a particularly interesting question. I've a take on it that isn't exactly the same as any of the answers, so bear with my coming to it so late.

The first thing to note, is that null in .NET is not entirely the same as null in some other contexts, though it can be used to model them.

In SQL for example, we might have 1 = null and 1 <> null both return null, because it's concept of null is closer to the mathematical, in which null is not equal to anything, including null, but nor is it precisely unequal to anything.

We can use C# null for this if we want, but that's not quite how the default meaning of null in .NET works.

For any reference type, null has a specific defined meaning, and possibly additional meanings provided by context.

The specific meaning is "there is no instance of this an object of this type".

Additional meanings in a given context could be "the integer value is in fact null, rather than matching any integer", or "there is no such collection of items, not even an empty one", or "this is the first such item, so there is no earlier one" and so on depending on how we make use of it. (Also, it could mean "oh dear, that really wasn't supposed to be null, better throw an exception").

Now, we might want to make heavy use of those additional meanings, to such an extent that we define cases in which it is meaningful for an object to be equal to null, or at the very least not unequal to null. However, we have the following limitations:

  1. The specific definition that null for a value of a reference type means there is no instance of that reference type will not go away.

  2. The semantics that x == y will always give the opposite result to x != y for a given x and y, will not go away.

Therefore:

  1. If we want a type where an instance can be equal to null, it must be a value type.

  2. We still have to have x != null return the opposite to x == null.

Now, since .NET 2.0 we've had a built-in that does precisely that: Nullable<T> (or T? in C# syntax). It also has a bit of extra support to help it behave well in the face of boxing (which makes it in man ways behave like a reference type, so without that extra support we'd have complications were x == null would return true but (object)x == null would return false.

It's also the case, that Nullable<T> can deal with pretty much any case in which we'd like to make use of this sort of slightly different semantics for null, meaning there isn't really any case left were we're likely to want to define an Equals() method that returns true when passed null.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top