清单<t>不起作用</t>

时间:2013-09-08 16:22:28

标签: 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 ((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();

2 个答案:

答案 0 :(得分:5)

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

这是第一件要解决的问题。我建议修剪数据库中的城市名称以获得理智,然后删除Trim检查中的Equality操作。这会让事情变得更简单。

第二个是解决为什么在数据库中花了很长时间:我强烈期望它在数据库中的表现要比本地好,特别是如果你有两个字段的索引。

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

编辑:另外,正如Scott指出的那样,你要么需要传入IEqualityComparer来执行相等比较让你的类型覆盖正常{ {1}}和Equals方法。目前你正处于两者之间(实现GetHashCode,但实际上没有提供比较器作为IEqualityComparer<T>Distinct构造函数的参数。通常,类型为自己实现HashSet是不寻常的。基本上,您 类型中实现“自然”相等性检查,您在实现IEqualityComparer的类型中实现独立的相等性检查。您没有 来实施IEqualityComparer<T> - 只是覆盖正常的IEquatable<T>方法会起作用 - 但同时实施Equals(object)通常是个好主意

另外,我还建议在不使用字符串连接的情况下计算哈希码。例如:

IEquatable<T>

答案 1 :(得分:3)

您需要界面IEquatable<T>而不是IEqualityComparer<T>(请务必阅读文档,尤其是“对实施者的说明”部分!)。 IEqualityComparer是您希望使用自定义比较器而不是内置于类中的默认比较器。

此外,您需要进行Jon mentioned GetHashCodeEquals不匹配的更改