X。 Equals(null) returns false(仅适用于不可为 null 的值类型)
x. Equals(null) returns false (for non-nullable value types only)
在阅读 this article 时,我看到 Object.Equals 重写应该 return false 如果仅针对不可为 null 的值调用 null 参数:
同时我阅读了给定的示例 - TwoDPoint - 是一个可为空的类型,但它与指南本身相矛盾。
那么,为可空类型重载 Equals 方法的最佳实践是什么?
TwoDPoint - is a nullable type
不,TwoDPoint
不是可空类型,Nullable Type 应该包含一个问号:
TwoDPoint?
是可空类型,它是 shorthand for 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);
TwoDPoint
是一个 class
类型,它是一个引用类型。因此,允许使用特殊值 null
作为参考。因此 TwoDPoint
类型的值 p
可能是 null
.
对于 class
类型,在 public bool Equals
非静态方法中,“this
”永远不会 null
,因此它是正确的return 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 value 类型 的特殊 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 reference。 "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'!
在阅读 this article 时,我看到 Object.Equals 重写应该 return false 如果仅针对不可为 null 的值调用 null 参数:
同时我阅读了给定的示例 - TwoDPoint - 是一个可为空的类型,但它与指南本身相矛盾。
那么,为可空类型重载 Equals 方法的最佳实践是什么?
TwoDPoint - is a nullable type
不,TwoDPoint
不是可空类型,Nullable Type 应该包含一个问号:
TwoDPoint?
是可空类型,它是 shorthand for 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);
TwoDPoint
是一个 class
类型,它是一个引用类型。因此,允许使用特殊值 null
作为参考。因此 TwoDPoint
类型的值 p
可能是 null
.
对于 class
类型,在 public bool Equals
非静态方法中,“this
”永远不会 null
,因此它是正确的return 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 value 类型 的特殊 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 reference。 "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'!