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

JCa*_*sso 2 c# oop

我在这里谈论C#语言.

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

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

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

x.Equals(null引用(在Visual Basic中为Nothing))返回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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

并创建四个实例:

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;
Run Code Online (Sandbox Code Playgroud)

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

int? i = null;
Run Code Online (Sandbox Code Playgroud)

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

我真正的问题是:

i.Equals(null); // returns true!
Run Code Online (Sandbox Code Playgroud)

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

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

Jar*_*Par 9

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

i? = null;
Run Code Online (Sandbox Code Playgroud)

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

Nullable<int> i = new Nullable<int>();
Run Code Online (Sandbox Code Playgroud)

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

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

Nullable<int> i = new Nullable<int>();
i.Equals(null);
Run Code Online (Sandbox Code Playgroud)

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

  • 请注意,_static_方法`Object.Equals(null,null)`将返回true,因此已经确定`null`等于`null`.调用`null.Equals(y)`时得到`NullReferenceException`的唯一原因是因为对引用类型的实例方法调用的语义要求; 它与"Equals"本身的语义无关.由于`Nullable <T>`不是引用类型,因此不适用. (2认同)