C# 不同的列表<;T>;不工作

C# 不同的列表<;T>;不工作,c#,linq,list,generics,collections,C#,Linq,List,Generics,Collections,我有一节比较器课 public partial class CityCountryID :IEqualityComparer<CityCountryID> { public string City { get; set; } public string CountryId { get; set; } public bool Equals(CityCountryID left, CityCountryID right) { if ((

我有一节比较器课

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();
    }
}
公共部分类CityCountryID:IEqualityComparer
{
公共字符串City{get;set;}
公共字符串CountryId{get;set;}
公共布尔等于(CityCountryID左,CityCountryID右)
{
如果((对象)左==null&&(对象)右==null)
{
返回true;
}
if((对象)left==null | |(对象)right==null)
{
返回false;
}
返回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中这样做,因为这个列表太大,对Everrrr来说太难了。为什么这在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();
List CityList=LoadData(“GetCityList”).ToList();
//var unique=新哈希集(CityList);
Console.WriteLine(“加载完成/检查副本”);
List unique=CityList.Distinct().ToList();

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

这是要解决的第一件事。我建议删除数据库中的城市名称以保持其完整性,然后删除
Equality
检查中的
Trim
操作。那会使事情简单得多

第二个问题是找出它在数据库中花费很长时间的原因:我强烈希望它在数据库中的性能比在本地更好,特别是如果您在这两个字段上有索引的话

下一步是考虑如果可能的话,让你的类型不变。允许对象的可变属性影响相等通常是个坏主意;如果在将对象用作字典中的键(或将其添加到

哈希集
)后更改了该对象的等式敏感属性,则很可能会发现即使使用完全相同的引用,也无法再次检索该对象

编辑:另外,正如Scott所指出的,您需要传入一个
IEqualityComparer
来执行相等比较,或者让您的类型覆盖正常的
Equals
GetHashCode
方法。目前,您处于两者之间的中间位置(实现了
IEqualityComparer
,但实际上没有提供一个比较器作为
Distinct
HashSet
构造函数的参数)。一般来说,一个类型为自己实现
IEqualityComparer
是不常见的。基本上,您要么在类型中实现“自然”相等检查,要么在实现
IEqualityComparer
的类型中实现独立相等检查。您不必实现
IEquatable
——只需重写正常的
Equals(object)
方法即可——但通常最好同时实现
IEquatable

作为旁白,我还建议不使用字符串连接来计算哈希代码。例如:

public override int GetHashCode()
{
    int hash = 17;
    hash = hash * 31 + CountryId.GetHashCode();
    hash = hash * 31 + City.GetHashCode();
    return hash;
}

您需要实现的接口不是
IEqualityComparer
(请务必阅读文档,尤其是“实现者注意事项””部分!)。IEqualityComparer是指希望使用自定义比较器而不是类内置的默认比较器


此外,您还需要对
GetHashCode
不匹配的
Equals

进行更改。您是否尝试过覆盖对象的
Equals
GetHashCode
?@I4V,这就是我上面所做的?你看到了不同的东西吗?Justin你正在实现
IEqualityComparer
接口,不一样。@事实上你必须在这里添加
override
关键字,重写2
Equals
GetHashCode
或将实现IEqualityComparer的
不同对象传递到
Distinct
。很好发现-我完全忽略了这一点!我在这两个字段上都有索引,但我在笔记本电脑虚拟机上通过db本地运行,这可能是它没有那么快的原因。@JustinHomes:我仍然希望它比把所有数据拉下来然后自己做同样的事情要快。也许你应该问另一个问题,显示你尝试过的SQL。我的SQL非常简单,我在两个字段上都有索引asc选择Distinct City,CountryId from City Code;我在这个表上还有一个主id。由于非唯一的城市、国家,此表中存在重复项,这正是我试图解决的问题。我可以问一下您使用的
GetHashCode()
,为什么
hash
会初始化为
17
(不是任何其他?)以及接下来的步骤吗?非常感谢。在运行mysql时,我有400万条记录,6分钟后就会超时。当我从c#运行它时,它会在30秒内完成。