[英]Distinct of List <T> not workiong
I have this class with comparer 我有比较器班
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();
}
}
I Tried using Hashset and Distinct but neither one is working. 我尝试使用Hashset和Distinct,但没有一个起作用。 i did not want to do this in db as the list was too big and too for everrrrrrrr.
我不想在db中执行此操作,因为列表太大,对于everrrrrrrr也是如此。 why is this not working in c#?
为什么这在C#中不起作用? i want to get a unique country, city list.
我想获得一个独特的国家/地区城市列表。
List<CityCountryID> CityList = LoadData("GetCityList").ToList();
//var unique = new HashSet<CityCountryID>(CityList);
Console.WriteLine("Loading Completed/ Checking Duplicates");
List<CityCountryID> unique = CityList.Distinct().ToList();
Your Equals
and GetHashCode
methods aren't consistent. 您的
Equals
和GetHashCode
方法不一致。 In Equals
, you're trimming the city name - but in GetHashCode
you're not. 在
Equals
,您正在修剪城市名称-但是在GetHashCode
您不是。 That means two equal values can have different hash codes, violating the normal contract. 这意味着两个相等的值可以具有不同的哈希码,这违反了常规合同。
That's the first thing to fix. 那是要解决的第一件事。 I would suggest trimming the city names in the database itself for sanity, and then removing the
Trim
operations in your Equality
check. 我建议修剪数据库本身中的城市名称以保持理智,然后在“
Equality
检查中删除“ Trim
操作。 That'll make things a lot simpler. 这会使事情变得简单得多。
The second is work out why it was taking a long time in the database: I'd strongly expect it to perform better in the database than locally, especially if you have indexes on the two fields. 第二个是弄清楚为什么它在数据库中要花很长时间的原因 :我强烈希望它在数据库中的性能要好于本地,尤其是当您在两个字段上都有索引时。
The next is to consider making your type immutable if at all possible. 下一步是考虑使类型尽可能不变。 It's generally a bad idea to allow mutable properties of an object to affect equality;
允许对象的可变属性影响相等性通常是一个坏主意。 if you change an equality-sensitive property of an object after using it as a key in a dictionary (or after adding it to a
HashSet
) you may well find that you can't retrieve it again, even using the exact same reference. 如果在将对象用作字典中的键之后(或将其添加到
HashSet
)更改对象的相等性敏感属性,则可能会发现您无法再次检索它,即使使用完全相同的引用也是如此。
EDIT: Also, as Scott noted, you either need to pass in an IEqualityComparer
to perform the equality comparison or make your type override the normal Equals
and GetHashCode
methods. 编辑:另外,正如Scott指出的那样,您要么需要传递
IEqualityComparer
来执行相等比较, 要么使您的类型重写常规的Equals
和GetHashCode
方法。 At the moment you're half way between the two (implementing IEqualityComparer<T>
, but not actually providing a comparer as an argument to Distinct
or the HashSet
constructor). 目前,您处于两者之间的一半(实现
IEqualityComparer<T>
,但实际上没有提供比较器作为Distinct
或HashSet
构造函数的参数)。 In general it's unusual for a type to implement IEqualityComparer
for itself. 通常,对于类型自己实现
IEqualityComparer
的类型是很不常见的。 Basically you either implement a "natural" equality check in the type or you implement a standalone equality check in a type implementing IEqualityComparer<T>
. 基本上,您可以在类型中实现“自然”相等性检查, 或者在实现
IEqualityComparer<T>
的类型中实现独立的相等性检查。 You don't have to implement IEquatable<T>
- just overriding the normal Equals(object)
method will work - but it's generally a good idea to implement IEquatable<T>
at the same time. 您没有实现
IEquatable<T>
-只是压倒一切正常Equals(object)
方法将工作-但它通常是实现一个不错的主意IEquatable<T>
在同一时间。
As an aside, I would also suggest computing a hash code without using string concatenation. 顺便说一句,我也建议不使用字符串连接来计算哈希码。 For example:
例如:
public override int GetHashCode()
{
int hash = 17;
hash = hash * 31 + CountryId.GetHashCode();
hash = hash * 31 + City.GetHashCode();
return hash;
}
You needed to implment the interface IEquatable<T>
not IEqualityComparer<T>
(Be sure to read the documentation, especially the " Notes to Implementers " section!). 您需要实现
IEquatable<T>
接口IEquatable<T>
不是IEqualityComparer<T>
(请务必阅读文档,尤其是“ 对实现者的注意事项 ”部分!)。 IEqualityComparer is when you want to use a custom comparer other than the default one built in to the class. IEqualityComparer是您要使用自定义比较器而不是内置于该类的默认比较器时。
Also you need to make the changes that Jon mentioned about GetHashCode
not matching Equals
你也需要做出改变乔恩提及有关
GetHashCode
不匹配Equals
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.