C# Enumerable之IEqualityComparer<>接口应用

时间:2021-05-01 20:48:15   收藏:0   阅读:36

在C#语言中,对Enumerable的查询、统计、分组等操作使用LINQ非常方便,LINQ的语法格式与SQL语言非常相似和便捷,而本文将介绍一种比LINQ使用更方便的方法,它就是Enumerable方法+Lambda表达式,Enumerable类提供了非常多的集合操作方法,如All、Any、Count、Max等等,其中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;
}

原文:https://www.cnblogs.com/zhaoshujie/p/14724710.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!