IEquatable <t> - C#</t>中.Equals(object obj)的最佳实践覆盖

时间:2013-08-07 15:33:02

标签: c# .net exception boolean equality

每当我写一个可能包含某些数据的新classstruct时,可能需要对其进行比较,我总是实施IEquatable<T>,因为这会提供{{1}使用强类型class/struct方法。

示例:

.Equals(T other)

除了为public struct Radius : IEquatable<Radius> { public Int32 TopLeft { get; set; } public Int32 TopRight { get; set; } public Int32 BottomLeft { get; set; } public Int32 BottomRight { get; set; } public bool Equals(Radius other) { return this.TopLeft == other.TopLeft && this.TopRight == other.TopRight && this.BottomLeft == other.BottomLeft && this.BottomRight == other.BottomRight; } } 提供实现之外,我还应该覆盖默认实现(.Equals(Radius other)

我这里有两个选项,我的问题是,哪些实现更好?

选项1是使用强制转换:

.Equals(object obj)

选项2是使用“as”关键字:

public override bool Equals(object obj)
{
    return this.Equals((Radius)obj);
}

我提出这个问题的原因是,如果无法将public override bool Equals(object obj) { return this.Equals(obj as Radius); } 强制转换为obj,则使用强制转换会抛出异常,而Radius如果不能强制转换为as因此,它只会nullthis进行检查,而不会抛出异常;那么抛出异常或者只返回null

会更好 编辑:正如很多SO同事所指出的那样,结构不能为空,因此第二个选项不适用于结构。因此,另一个问题浮出水面:false被覆盖的实现是否应该与结构和类相同?

3 个答案:

答案 0 :(得分:7)

Equals()方法must never throw an exception

不同类型的对象仅仅是不相等的。

引用documentation

  

Equals的实现不得抛出异常;他们应该总是返回一个值。例如,如果obj为null,则Equals方法应该返回false而不是抛出ArgumentNullException。

答案 1 :(得分:5)

正如@SLaks已经提到的那样Equals()永远不应该抛出。

在这个特殊情况下,我认为使用is运算符和演员表可以帮助你:

public override bool Equals(object obj)
{
     if(obj is Radius)
         return Equals((Radius)obj);

     return false;
}

如果您有 class ,则只需使用as运算符:

public override bool Equals(object obj)
{
     return Equals(obj as MyObj);
}

public bool Equals(MyObj obj)
{
     if(ReferenceEquals(obj, null))
         return false;

     // ToDo: further checks for equality.
}

答案 2 :(得分:-1)

我个人的意见是使用第二个选项,或者如果对象是“Radius”,则甚至事先检查然后返回false以使意图更清晰