与列表不同,而不是工作

本文关键字:工作 不同 列表 | 更新日期: 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();

与列表<T>不同,而不是工作

您的EqualsGetHashCode方法不一致。在Equals中,您正在修剪城市名称 - 但在GetHashCode中,您不是。这意味着两个相等的值可以有不同的哈希码,违反了正常的合约。

这是要解决的第一件事。我建议修剪数据库本身中的城市名称以确保理智,然后在Equality检查中删除Trim操作。这将使事情变得简单得多。

第二个是弄清楚为什么在数据库中花费很长时间:我强烈希望它在数据库中的性能比本地更好,特别是如果你在这两个字段上有索引。

接下来是考虑使你的类型不可变(如果可能的话)。允许对象的可变属性影响相等性通常是一个坏主意;如果在字典中将对象的键用作键(或将其添加到HashSet后)更改对象的相等敏感属性,则很可能会发现即使使用完全相同的引用也无法再次检索它。

编辑:此外,正如Scott指出的那样,您要么需要传入IEqualityComparer来执行相等比较,要么使您的类型覆盖正常的EqualsGetHashCode方法。目前,您介于两者之间(实现IEqualityComparer<T>,但实际上并没有提供比较器作为DistinctHashSet构造函数的参数)。通常,类型为自己实现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的更改