X。 Equals(null)返回false(仅适用于不可为空的值类型)

问题描述 投票:-1回答:2

在阅读this article时,我看到Object.Equals覆盖应该返回false,如果仅为非可空值调用null参数:

enter image description here

同时我读到给定的例子 - TwoDPoint - 是一个可以为空的类型,但它与指南本身相矛盾。

enter image description here

那么,为可空类型重载Equals方法的最佳实践是什么呢?

c# equality msdn
2个回答
2
投票

TwoDPointclass类型,是参考类型。因此,允许特殊值null作为参考。所以p类型的值TwoDPoint可能是null

使用class类型,你在public bool Equals非静态方法中,“this”永远不是null,因此每当false参数是p时返回null是正确的。

// Example 1
var t = new Point(10, 4);
var p = (Point)null;
var isEqual = t.Eqauls(p); // should return 'false', therefore the code you ask about

// Example 2
var t = (Point)null;
var p = (Point)null;
var isEqual = t.Eqauls(p); // 'NullReferenceException', method not called

在上面,您可以看到它对参考类型的作用。

使用用于可空值类型的特殊Nullable<>类型,事情有点不同。但是好消息是你不必编写Nullable<>.Equals的代码,因为它已经在.NET Framework中了。

// Example 3
var t = (TimeSpan?)TimeSpan.FromHours(3.5);
var p = (TimeSpan?)null;
var isEqual = t.Equals(p); // will return 'false'

// Example 4
var t = (TimeSpan?)null;
var p = (TimeSpan?)null;
var isEqual = t.Equals(p); // OK, method will return 'true'!

在示例4中,不发生空引用。存在的“null”是Nullable<TimeSpan>结构的值,其HasValue属性等于false。在Equals中声明了Nullable<>方法(在本例中为覆盖),因此不会发生装箱。

不同:

// Example 5
var t = (TimeSpan?)null;
var type = t.GetType(); // 'GetType' declared in class (System.Object), boxing, 'NullReferenceException'!

1
投票

TwoDPoint - 是一个可以为空的类型

不,TwoDPoint不是可以为空的类型,Nullable Type应该包含一个问号:

TwoDPoint?是一个可以为空的类型,它是Nullable<TwoDPoint>的简写

因此,如果您在可空类型上调用Equals,它将不会调用覆盖/重载方法。

TwoDPoint? a = new TwoDPoint();
var b = (TwoDPoint)a;

// call Nullable<TwoDPoint>.Equals, not TwoDPoint.Equals
a.Equals(b);

// call TwoDPoint.Equals
b.Equals(b);
© www.soinside.com 2019 - 2024. All rights reserved.