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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM