开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜