Is Nullable<T>.Equals Method Implementation Wrong?
I am talking about C# language here.
Definition of Object.Equals(Object) method in msdn is:
Determines whether the specified Object is equal to the current Object.
If two objects are equal it returns true, however if they are null it returns false:
x.Equals(a null reference (Nothing in Visual Basic)) returns false.
Why? Because null is not an object.
A NullReferenceException is thrown if the object paremeter is null.
and also we have this:
x.Equals(y) returns the same value as y.Equals(x).
No problem at all till here. It is very similar to Java. But C# also provides a System.Nullable
struct for non-nullable types. As far as I know, a struct is an object. It inherits Object.Equals method.
If I have a struct like this:
struct Car
{
public string Make;
public string Model;
public uint Year;
public Car(string make, string model, uint year)
{
Make = make;
Model = model;
Year = year;
}
}
And create four instances:
Car car1 = new Car("make", "model", 2009);
Car car2 = new Car("make", "model", 2009);
Car car3 = new Car("make", "model", 2008);
car1.Equals(car2); // will return true
car1.Equals(car3); // will return false;
And as far as I know we can't set a struct to a null value. But System.Nullable is a struct and we can do compile this without any errors:
int? i = null;
(I hope that someone can explain this also. Is it a struct or something else?)
My real question is:
i.Equals(null); // returns true!
(Normally x.Equals(y) = y.Equals(x) Of course null.Equals(i) is not valid here... )
Obviously Object.Equals method is overridden here. Maybe it is documented and this is specified. But is this approach correct/nice开发者_开发问答 ? If so what is the difference between == and Equals method for Nullable values?
I think your confusion is rooted in the following line
i? = null;
This does not actually create a null value variable. It's essentially syntatic sugar for the following
Nullable<int> i = new Nullable<int>();
The resulting property HasValue on i will have the value false. It is not null but instead a value type with empty values. Or just an empty nullable. IMHO, the best way to think of this is that null is convertible to an empty Nullable<T>
for any given T.
Knowing that it makes the line i.Equals(null) a bit easier to understand. It's syntatic sugar for the following
Nullable<int> i = new Nullable<int>();
i.Equals(null);
The type Nullable<T>
only overrides Equals(object). The implementation of this method though considers a null value to be Equal to an empty nullable value. So it's behaving correctly.
To answer your side question, Nullable is a struct with a T: Struct constraint. So, even though int? i = null; is null, i is an instance of the Nullable struct.
精彩评论