Nullable <t> .Equals方法实现错误?</t>

时间:2009-10-08 23:40:23

标签: c# oop

我在这里谈论C#语言。

msdn中Object.Equals(Object)方法的定义是:

  

确定是否指定   Object等于当前的Object。

如果两个对象相等,则返回true,但如果它们为null,则返回false:

  

x.Equals(空引用(Nothing in a null)   Visual Basic))返回false。

为什么呢?因为null不是对象。

如果对象参数为空,则抛出NullReferenceException。

我们也有:

  

x.Equals(y)返回相同的值   y.Equals(X)。

直到这里都没问题。它与Java非常相似。但是C#还为非可空类型提供了System.Nullable结构。据我所知,结构是一个对象。它继承了Object.Equals方法。

如果我有这样的结构:

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;
        }
    }

创建四个实例:

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;

据我所知,我们无法将结构设置为空值。但是System.Nullable是一个结构,我们可以编译它而没有任何错误:

int? i = null;

(我希望有人也能解释一下。它是一个结构还是其他东西?)

我真正的问题是:

i.Equals(null); // returns true!

(通常x.Equals(y)= y.Equals(x)当然null.Equals(i)在这里无效...)

显然,Object.Equals方法在这里被覆盖。也许它是有记录的,这是指定的。但这种方法是正确/好吗?如果是这样,可以为Nullable值的==和Equals方法之间有什么区别?

2 个答案:

答案 0 :(得分:9)

我认为你的困惑植根于以下一行

i? = null;

这实际上并不创建空值变量。它基本上是以下的合成糖

Nullable<int> i = new Nullable<int>();

i上的结果属性HasValue的值为false。它不是null,而是具有空值的值类型。或者只是一个空的可空。恕我直言,想到这一点的最好方法是,对于任何给定的T,null可以转换为空Nullable<T>

知道它使i.Equals(null)行更容易理解。它是以下的合成糖

Nullable<int> i = new Nullable<int>();
i.Equals(null);

类型Nullable<T>仅覆盖Equals(对象)。此方法的实现虽然将null值视为等于空的可空值。所以它的行为正确。

答案 1 :(得分:2)

要回答您的问题,Nullable是一个具有T:Struct约束的结构。那么,即使是int? i = null;为null,我是Nullable结构的一个实例。