zoukankan      html  css  js  c++  java
  • C#中List集合操作IEqualityComparer正确使用方法

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

    对于普通的string、及其他基础类型并不需要实现,但是当你自己的引用类型实体需要进行比较就需要实现,特别是比较复杂的判等公示

    IEqualityComparer 怎么实现

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

    resharper插件可以默认用alt-insert快捷键插入实现

    我这里有四个属性要比较

    MemoId:string

    Content:string

    Title:string

    Tags:List

    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的默认实现

    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)进行比较

    如果之前实现了 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这样实现有什么负面效果待后续考证,目前没有发现副作用

  • 相关阅读:
    【Visual C++】游戏开发笔记之六——游戏画面绘图(三)透明特效的制作方法
    【不定期更新】游戏开发中的一些良好习惯与技术技巧
    【Visual C++】游戏开发笔记之七——基础动画显示(一)定时器的使用
    【超级经典】程序员装B指南(转)
    Gentoo安装小记
    图形学中的贴图采样、走样与反走样等
    面试题之银行业务调度系统
    四川雅安芦山加油挺住
    ZOJ 3223 Journey to the Center of the Earth
    android中ListView拖动时背景黑色的问题
  • 原文地址:https://www.cnblogs.com/enigmaxp/p/8718299.html
Copyright © 2011-2022 走看看