Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equals comparison with a nullable type on another nullable type

Tags:

c#

I have two objects(of the same type) which contains a prop myprop of type byte?. The properties are set to null. When I perform objectA.myprop.Equals(objectB.myprop) I get 'true' as a result although the MSDN code sample states that "Equals applied to any null object returns false."

I'm guessing C# uses a seperate overload for nullable type comparisons. I would like to know how C# internally treats objects versus nullable types in this case.

like image 673
arviman Avatar asked Nov 23 '11 21:11

arviman


2 Answers

When you call it like that, it will use Nullable<T>.Equals(object) which shows the expected behaviour in the documentation:

(Return value is true if...)

The HasValue property is false, and the other parameter is null. That is, two null values are equal by definition.

Likewise for equality via ==, section 7.3.7 of the C# 4 spec (lifted operators) states:

For the equality operators == [and] != a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is bool. The lifted form is constructed by adding a single ? modifier to each operand type. The lifted operator considers two null values equal, and a null value unequal to any non-null value. If both operands are non-null, the lifted operator unwraps the operands and applies the underlying operator to produce the bool result.

(Emphasis mine.)

This is a general rule, in terms of the implementation of object.Equals:

The following statements must be true for all implementations of the Equals method. In the list, x, y, and z represent object references that are not null.

[...]

  • x.Equals(null) returns false.

So while it is a general rule, it doesn't apply in this specific case - because the value here isn't an object reference - it's a value type value. It's still somewhat surprising, unless you basically accept that Nullable<T> is a bit of a special case - it has specific C# compiler support and it has CLR support in terms of boxing and unboxing.

like image 128
Jon Skeet Avatar answered Sep 21 '22 12:09

Jon Skeet


I have edited this for clarity.

You misunderstood that quote. To give the full context:

string s = null;
string t = String.Empty; // Logically the same as ""

// Equals applied to any null object returns false.
bool b = (t.Equals(s));

This is saying that a reference to a string object does not equate to a null reference. You took that quote out of context, and interpreted it as a general rule, which it is not. However this is referring to references NOT nullable types.

When you are dealing with nullable primitive types:

The actual rule is

An equality comparison of two nullable types that are both null evaluates to true.

http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx

like image 39
Joe Avatar answered Sep 19 '22 12:09

Joe