IEqualityComparer主要适用于定义方法以支持对象的相等比较。可以实现集合的自定义相等比较。即,您可以创建自己的相等定义,并指定此定义与接受 IEqualityComparer 接口的集合类型一起使用。
IEqualityComparer 接口包含两个方法,方法
名称 说明
Equals 确定指定的对象是否相等。
GetHashCode 返回指定对象的哈希代码。
整体来说,比较好理解
Equals方法:自反的、对称的和可传递的。也就是说,如果此方法用于将某个对象与其自身比较,则它将返回 true;如果对 y 和 x 执行此方法返回 true,则对 x 和 y 这两个对象也返回 true;如果对 x 和 y 执行此方法返回 true,并且对 y 和 z 执行此方法也返回 true,则对 x 和 z 这两个对象也返回 true。
实现需要确保如果对两个对象 x 和 y 执行 Equals 方法返回 true,则对 x 和 y 分别执行 GetHashCode 方法所返回的值必须相等。
<//www.w3.org/1999/xhtml:sentencetext xmlns="http://www.w3.org/1999/xhtml">
GetHashCode方法:实现需要确保如果对两个对象 x 和 y 执行 Equals 方法返回 true,则对 x 和 y 分别执行 GetHashCode 方法所返回的值必须相等。
<//www.w3.org/1999/xhtml:sentencetext xmlns="http://www.w3.org/1999/xhtml"> 当我们用Linq操作我们自定义的对象时,我们会发现有些方法直接使用的话根本不起作用,比如:Distinct、Except、Intersect等扩展方法。这是就需要定义IEqualityComparer接口来判断两个对象的相等性。
下面给出简单实例说明:
首先,我们定义一个类(代码出自:www.jianshengjt.com)
[csharp]
public class SellerTypeIdentify
{
/// <summary>
/// 商户类型ID
/// </summary>
public string SellerTypeID
{
get;
set;
}
public string SellerName
{
get;
set;
}
}
定义一个以SellerTypeID为基础的比较器
[csharp]
public class SellerTypeIdentifyComparer : IEqualityComparer<SellerTypeIdentify>
{
// SellerType are equal if their names and product numbers are equal.
public bool Equals(SellerTypeIdentify x, SellerTypeIdentify y)
{
//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
return x.SellerTypeID == y.SellerTypeID;
}
public int GetHashCode(SellerTypeIdentify product)
{
//Check whether the object is null
if (Object.ReferenceEquals(product, null)) return 0;
//Get hash code for the SellerTypeID field if it is not null.
int SellerTypeId = product.SellerTypeID == null ? 0 : product.SellerTypeID.GetHashCode();
//Calculate the hash code for the SellerType.
return SellerTypeId;
}
}
初始化数据
[csharp]
public static List<SellerTypeIdentify> GetMainData()
{
List<SellerTypeIdentify> sellerTypeList = new List<SellerTypeIdentify>();
sellerTypeList.Add(new SellerTypeIdentify { SellerTypeID = "00000001", SellerName = "Name0001" });
sellerTypeList.Add(new SellerTypeIdentify { SellerTypeID = "00000002", SellerName = "Name0002" });
sellerTypeList.Add(new SellerTypeIdentify { SellerTypeID = "00000003", SellerName = "Name0003" });
return sellerTypeList;
}
public static List<SellerTypeIdentify> GetSuppData()
{
List<SellerTypeIdentify> sellerTypeList = new List<SellerTypeIdentify>();
sellerTypeList.Add(new SellerTypeIdentify { SellerTypeID = "00000002", SellerName = "Name0001" });
sellerTypeList.Add(new SellerTypeIdentify { SellerTypeID = "00000001", SellerName = "Name0002" });
sellerTypeList.Add(new SellerTypeIdentify { SellerTypeID = "00000003", SellerName = "Name0003" });
sellerTypeList.Add(new SellerTypeIdentify { SellerTypeID = "00000004", SellerName = "Name0004" });
return sellerTypeList;
}
就拿Distinct和SequenceEqual来说
[html]
List<SellerTypeIdentify> sellerTypeMainList = new List<SellerTypeIdentify>();
sellerTypeMainList = Program.GetMainData();
List<SellerTypeIdentify> sellerTypeSuppList = new List<SellerTypeIdentify>();
sellerTypeSuppList = Program.GetSuppData();
int mainSellerCount = sellerTypeMainList.Distinct(new SellerTypeIdentifyComparer()).Count();
int suppSellerCount = sellerTypeSuppList.Distinct(new SellerTypeIdentifyComparer()).Count();
List<bool> xquery = new List<bool>();
if (suppSellerCount <= mainSellerCount)
{
foreach (SellerTypeIdentify s in sellerTypeSuppList.Distinct(new SellerTypeIdentifyComparer()).OrderBy(x => x.SellerTypeID))
{
xquery.Add(sellerTypeMainList.OrderBy(x => x.SellerTypeID).Contains(s, new SellerTypeIdentifyComparer()));
}
}
else
{
Console.WriteLine("NOT CONTAINS1");
}
if (xquery.Contains(false))
{
Console.WriteLine("NOT CONTAINS2");
}
bool IsEqual = sellerTypeMainList.OrderBy(x => x.SellerTypeID).SequenceEqual(sellerTypeSuppList.OrderBy(x => x.SellerTypeID), new SellerTypeIdentifyComparer());
if (IsEqual)
{
Console.WriteLine("Equal");
}
else
{
Console.WriteLine("Not Equal");
}