zoukankan      html  css  js  c++  java
  • C# LINQ之IEqualityComparer<>接口应用

    在C#语言中,对集合的条件查询、分组统计等操作使用LINQ非常方便,LINQ的语法格式与SQL非常相似和便捷,而LINQ扩展方法配合Lambda更为简洁,如All、Any、Count、MaxEnumerable类扩展方法,其中Distinct、Intersect、Contains等大量方法中使用了IEqualityComparer<>接口,以实现对象的比较,先看一个查询两个集合交集的代码示例:

    public class Product
    {
        public string Name { get; set; }
        public int Code { get; set; }
    }
    
    // 产品类的自定义比较器
    class ProductComparer : IEqualityComparer<Product>
    {
    	// 实现接口`Equals`方法
        public bool Equals(Product x, Product y)
        {
            // 比较两个对象的内存地址是否一致
            if (Object.ReferenceEquals(x, y)) return true;
            if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
                return false;
            return x.Code == y.Code && x.Name == y.Name;
        }
        
    	// 实现接口`GetHashCode`方法
        public int GetHashCode(Product product)
        {
            if (Object.ReferenceEquals(product, null)) return 0;
            int hashProductName = product.Name == null ? 0 : product.Name.GetHashCode();
            int hashProductCode = product.Code.GetHashCode();
            return hashProductName ^ hashProductCode;
        }
    }
    
    static void Main(string[] args)
    {
    	// 初始化集合数据
        Product[] store1 = { new Product { Name = "apple", Code = 9 },
                             new Product { Name = "orange", Code = 4 } };
        Product[] store2 = { new Product { Name = "apple", Code = 9 },
                             new Product { Name = "lemon", Code = 12 } };
    	
        // 查询store1与store2的交集    
        IEnumerable<Product> duplicates = store1.Intersect(store2, new ProductComparer());
        
        foreach (var product in duplicates)
        	Console.WriteLine(product.Name + " " + product.Code);
    }
    
    /*
        代码输出结果: apple 9
    */
    
    

    看了以上代码后,有的小伙伴会问了,为什么要实现IEqualityComparer<>接口?实现IEqualityComparer<>接口需要注意什么?我来为大家解惑

    1. 为什么要实现IEqualityComparer<>接口

    是为了复杂类型(类)对象的比较,虽然store1[0]store2[0]的属性值都一样,但它们是两个不同的对象,如果GetHashCode方法代码如下,则结果为空。

    public int GetHashCode(Product product)
    {
        return product.GetHashCode();
    }
    

    2. 如何实现IEqualityComparer<>接口

    首先,我们需要了解IEqualityComparer<>接口的两个方法的作用和逻辑,.NET处理时先比较两个对象GetHashCode方法返回的哈希值是否相等,如果不相等则直接返回,不再执行Equals方法,如果哈希值相等则执行Equals方法继续比较!为什么要用两个方法去对比呢?原因是GetHashCode方法比Equals方法效率更高,所以先执行GetHashCode方法。依据上述分析,把示例中GetHashCode方法改为如下代码,则结果是相同的。

    public int GetHashCode(Product product)
    {
        return 0;
    }
    
  • 相关阅读:
    nginx 配置上传文件大小限制
    linux大文件截取某个日期后面的所有内容
    软件架构笔记 五
    软件架构笔记 四
    软甲架构笔记 三
    软件架构笔记 二
    软件架构笔记 一
    c# 生成的没用文件
    c# 两个软件传参
    c# 四则运算出错
  • 原文地址:https://www.cnblogs.com/zhaoshujie/p/14724710.html
Copyright © 2011-2022 走看看