与列表不同,而不是工作
本文关键字:工作 不同 列表 | 更新日期: 2023-09-27 18:30:39
我有这个类与比较器
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();
}
}
我尝试使用哈希集和独特,但两者都不起作用。 我不想在 db 中执行此操作,因为列表太大了,而且对于每个 rrrrrrrr 来说都太大了。 为什么这在 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>
不IEqualityComparer<T>
安装界面(请务必阅读文档,尤其是"实现者说明"部分!IEqualityComparer 是指您想要使用自定义比较器,而不是类中内置的默认比较器。
您还需要进行 Jon 提到的关于GetHashCode
不匹配Equals
的更改