![](/img/trans.png)
[英]Questions about IEqualityComparer<T> / List<T>.Distinct()
[英]Distinct of List <T> not workiong
我有比较器班
public partial class CityCountryID :IEqualityComparer<CityCountryID>
{
public string City { get; set; }
public string CountryId { get; set; }
public bool Equals(CityCountryID left, CityCountryID right)
{
if ((object)left == null && (object)right == null)
{
return true;
}
if ((object)left == null || (object)right == null)
{
return false;
}
return left.City.Trim().TrimEnd('\r', '\n') == right.City.Trim().TrimEnd('\r', '\n')
&& left.CountryId == right.CountryId;
}
public int GetHashCode(CityCountryID obj)
{
return (obj.City + obj.CountryId).GetHashCode();
}
}
我尝试使用Hashset和Distinct,但没有一个起作用。 我不想在db中执行此操作,因为列表太大,对于everrrrrrrr也是如此。 为什么这在C#中不起作用? 我想获得一个独特的国家/地区城市列表。
List<CityCountryID> CityList = LoadData("GetCityList").ToList();
//var unique = new HashSet<CityCountryID>(CityList);
Console.WriteLine("Loading Completed/ Checking Duplicates");
List<CityCountryID> unique = CityList.Distinct().ToList();
您的Equals
和GetHashCode
方法不一致。 在Equals
,您正在修剪城市名称-但是在GetHashCode
您不是。 这意味着两个相等的值可以具有不同的哈希码,这违反了常规合同。
那是要解决的第一件事。 我建议修剪数据库本身中的城市名称以保持理智,然后在“ Equality
检查中删除“ Trim
操作。 这会使事情变得简单得多。
第二个是弄清楚为什么它在数据库中要花很长时间的原因 :我强烈希望它在数据库中的性能要好于本地,尤其是当您在两个字段上都有索引时。
下一步是考虑使类型尽可能不变。 允许对象的可变属性影响相等性通常是一个坏主意。 如果在将对象用作字典中的键之后(或将其添加到HashSet
)更改对象的相等性敏感属性,则可能会发现您无法再次检索它,即使使用完全相同的引用也是如此。
编辑:另外,正如Scott指出的那样,您要么需要传递IEqualityComparer
来执行相等比较, 要么使您的类型重写常规的Equals
和GetHashCode
方法。 目前,您处于两者之间的一半(实现IEqualityComparer<T>
,但实际上没有提供比较器作为Distinct
或HashSet
构造函数的参数)。 通常,对于类型自己实现IEqualityComparer
的类型是很不常见的。 基本上,您可以在类型中实现“自然”相等性检查, 或者在实现IEqualityComparer<T>
的类型中实现独立的相等性检查。 您没有实现IEquatable<T>
-只是压倒一切正常Equals(object)
方法将工作-但它通常是实现一个不错的主意IEquatable<T>
在同一时间。
顺便说一句,我也建议不使用字符串连接来计算哈希码。 例如:
public override int GetHashCode()
{
int hash = 17;
hash = hash * 31 + CountryId.GetHashCode();
hash = hash * 31 + City.GetHashCode();
return hash;
}
您需要实现IEquatable<T>
接口IEquatable<T>
不是IEqualityComparer<T>
(请务必阅读文档,尤其是“ 对实现者的注意事项 ”部分!)。 IEqualityComparer是您要使用自定义比较器而不是内置于该类的默认比较器时。
你也需要做出改变乔恩提及有关GetHashCode
不匹配Equals
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.