C#中List集合操做IEqualityComparer正确使用方法

Except、Intersect、Union方法中的IEqualityComparer 怎么使用

对于普通的string、及其余基础类型并不须要实现,可是当你本身的引用类型实体须要进行比较就须要实现,特别是比较复杂的判等公示c#

IEqualityComparer 怎么实现

须要实现bool Equals(CNMemo x, CNMemo y)int GetHashCode(CNMemo obj)方法,并继承IEqualityComparer ,这里CNMemo是我定义的类 插件

resharper插件能够默认用alt-insert快捷键插入实现code

我这里有四个属性要比较继承

MemoId:string接口

Content:stringget

Title:stringstring

Tags:List hash

private sealed class CnMemoEqualityComparer : IEqualityComparer<CNMemo>
{
    public bool Equals(CNMemo x, CNMemo y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (ReferenceEquals(x, null)) return false;
        if (ReferenceEquals(y, null)) return false;
        if (x.GetType() != y.GetType()) return false;
        return string.Equals(x.MemoId, y.MemoId) && string.Equals(x.Content, y.Content) && string.Equals(x.Title, y.Title) && ((x.Tags == null && y.Tags == x.Tags) ||
    (x.Tags != null && y.Tags != null && x.Tags.Count == y.Tags.Count &&
     !x.Tags.Except(y.Tags).Any()));
    }

    public int GetHashCode(CNMemo obj)
    {
        return obj.ToString().GetHashCode();
    }
}
public static IEqualityComparer<CNMemo> CnMemoComparer { get; } = new CnMemoEqualityComparer();

注意: 这里的方法中会先执行GetHashCode方法,若是GetHashCode方法返回的是不相同的值,那就直接忽略Equals方法,因此我在GetHashCode中没有使用resharper的默认实现it

public int GetHashCode(CNMemo obj)
{
    unchecked
    {
        var hashCode = (obj.MemoId != null ? obj.MemoId.GetHashCode() : 0);
        hashCode = (hashCode * 397) ^ (obj.Content != null ? obj.Content.GetHashCode() : 0);
        hashCode = (hashCode * 397) ^ (obj.Title != null ? obj.Title.GetHashCode() : 0);
        hashCode = (hashCode * 397) ^ (obj.Tags != null ? obj.Tags.GetHashCode() : 0);
        return hashCode;
    }
}

由于这样Tags引用地址不同会致使GetHashCode不一致,obj.ToString().GetHashCode()若是tostring方法返回内容相同,那么就会使用bool Equals(CNMemo x, CNMemo y)进行比较io

若是以前实现了 IEquatable<CNMemo>也可以使用x.Equals(y)来完成比较,这样比较代码就不用拷贝两份了。

使用的时候就这样new List<CNMemo>() { memo1 }.Except(new List<CNMemo>() { memo2 }, CNMemo.CnMemoComparer)

IEquatable 接口

若是实现了 IEquatable<CNMemo>而且注意GetHashCode方法的实现注意上面的问题,也可直接使用new List<CNMemo>() { memo1 }.Except(new List<CNMemo>() { memo2 })

可是默认GetHashCode这样实现有什么负面效果待后续考证,目前没有发现反作用

相关文章
相关标签/搜索