c# - Nullable<T>.Equals 方法实现是否错误?

标签 c# oop

我在这里谈论的是 C# 语言。

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

Determines whether the specified Object is equal to the current Object.

如果两个对象相等则返回真,但是如果它们为空则返回假:

x.Equals(a null reference (Nothing in Visual Basic)) returns false.

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

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

还有这个:

x.Equals(y) returns the same value as y.Equals(x).

到这里完全没有问题。它与 Java 非常相似。但是 C# 还为不可为 null 的类型提供了 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 方法有什么区别?

最佳答案

我认为您的困惑源于以下行

i? = null;

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

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

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

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

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

类型Nullable<T>只覆盖 Equals(object)。尽管此方法的实现将空值视为等于空的可空值。所以它的行为是正确的。

关于c# - Nullable<T>.Equals 方法实现是否错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1541132/

相关文章:

c# - 自定义 DataGridViewCheckBoxCell 视觉更新在编辑模式下不起作用

c# - 模型的 XNA 方向

c# - 从 NetworkStream 异步读取时出错

java - 像 getSystemService() 这样的 "String-Based"API 有什么好处?

c++ - "Cannot instantiate abstract class"错误

php - 为什么覆盖方法参数违反了 PHP 中的严格标准?

c# - SignInManager.PasswordSignInAsync 抛出空对象异常

java - 在 Java 中用于类定义和声明的单独文件

OOP:创建电话号码对象或地址对象会有多远?

c# - 如何构建可以在窗口之间拖放用户控件的 WPF 应用程序?