等于方法实现助手(C#)

Jad*_*ias 8 .net c# equals iequatable gethashcode

每次我写一些数据类时,我通常会花很多时间编写IEquatable实现.

我写的最后一堂课是这样的:

public class Polygon
{
    public Point[] Vertices { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

实现IEquatable是非常有用的.当然C#3.0/LINQ有很多帮助,但顶点可以移位和/或以相反的顺序移动,这给Equals方法增加了很多复杂性.在经过多次单元测试和相应的实现后,我放弃了,并将我的应用程序更改为仅接受三角形,其中IEquatable实现只需要完全覆盖11个单元测试.

有什么工具或技术可以帮助实现Equals和GetHashCode吗?

Dre*_*kes 8

我使用ReSharper生成平等成员.IEquatable<T>如果你愿意的话,它可以选择实现以及覆盖操作符(当然你从来没有这样做,但它仍然很酷).

Equals的实现包括重写Object.Equals(Object),以及强类型变体(可以避免不必要的类型检查).较小类型的版本在执行类型检查后调用强类型版本.强类型版本执行引用相等性检查(Object.ReferenceEquals(Object,Object)),然后比较所有字段的值(嗯,只有那些告诉生成器要包含的字段).

至于GetHashCode,GetHashCode组合字段值的智能因子化(unchecked如果使用编译器checked选项,则使用以避免溢出异常).在组合之前,每个字段的值(除第一个之外)乘以素数.您还可以指定哪些字段永远不会为null,并且它将删除任何空检查.

这是您Polygon通过ALT+Insert选择" Generate Equality Members " 获得的课程内容:

public class Polygon : IEquatable<Polygon>
{
    public Point[] Vertices { get; set; }

    public bool Equals(Polygon other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return Equals(other.Vertices, Vertices);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != typeof (Polygon)) return false;
        return Equals((Polygon) obj);
    }

    public override int GetHashCode()
    {
        return (Vertices != null ? Vertices.GetHashCode() : 0);
    }
}
Run Code Online (Sandbox Code Playgroud)

我上面谈到的一些功能不适用,因为只有一个字段.另请注意,它尚未检查数组的内容.

总的来说,ReSharper只需几秒钟即可完成许多出色的代码.而且这个功能在我的列表中相当低,这使得ReSharper成为一个了不起的工具.

  • Equals(obj)覆盖对我来说看起来不是很好的代码.简单地说返回this.Equals(obj as Polygon)是不是更自然;? (2认同)