繁体   English   中英

名单不同 <T> 不努力

[英]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();

您的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>接口IEquatable<T>不是IEqualityComparer<T> (请务必阅读文档,尤其是“ 对实现者的注意事项 ”部分!)。 IEqualityComparer是您要使用自定义比较器而不是内置于该类的默认比较器时。

你也需要做出改变乔恩提及有关GetHashCode不匹配Equals

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM