获得LIST明显的通用方法<

时间:2016-10-19 18:18:43

标签: c# generic-collections

我试图比较(属性的值)List中的类型实例并消除重复。 根据MSDN GetHashCode()是比较两个对象的方法之一。

  

哈希码用于高效插入和查找   基于哈希表的集合。哈希码不是   永久价值

考虑到这一点,我开始将我的扩展方法编写为下面的

 public static class Linq 
    {
  public static IEnumerable<T> DistinctObjects<T>(this IEnumerable<T> source)
        {
            List<T> newList = new List<T>();
            foreach (var item in source)
            {
                if(newList.All(x => x.GetHashCode() != item.GetHashCode()))
                    newList.Add(item);
            }
            return newList;
        }
}

这个条件总是给我false,尽管对象的数据是相同的。

newList.All(x => x.GetHashCode() != item.GetHashCode())

最后我想像

一样使用它
MyDuplicateList.DistinctObjects().ToList();

如果比较对象的所有字段太多,我可以像使用

一样使用它
 MyDuplicateList.DistinctObjects(x=>x.Id, x.Name).ToList();

在这里,我告诉只比较这些对象的这两个字段。

2 个答案:

答案 0 :(得分:3)

在阅读您的评论后,我会提出这个解决方案:

   public static IEnumerable<TSource> DistinctBy<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
    {
        HashSet<TResult> set = new HashSet<TResult>();

        foreach(var item in source)
        {
            var selectedValue = selector(item);

            if (set.Add(selectedValue))
                yield return item;
        }
    }

然后你可以像这样使用它:

var distinctedList = myList.DistinctBy(x => x.A);

或类似的多个属性:

var distinctedList = myList.DistinctBy(x => new {x.A,x.B});

此解决方案的优点是您可以准确指定应区分哪些属性,并且不必为每个对象覆盖EqualsGetHashCode。您需要确保可以比较您的属性。

答案 1 :(得分:0)

您不需要为此创建自己的自定义通用方法。而是为您的数据类型提供自定义EqualityComparar

var myDuplicates = myList.Distinct(new MyComparer());

您可以像这样定义自定义Comparer:

public class MyComparer : IEqualityComparer<Mine>
{
    public bool Equals(Mine x, Mine y)
    {
        if (x == null && y == null) return true;            
        if (x == null || y == null) return false;
        return x.Name == y.Name && x.Id == y.Id;
    }

    public int GetHashCode(Mine obj)
    {
        return obj.Name.GetHashCode() ^ obj.Id.GetHashCode();
    }
}

编辑:我最初在这里有错误的代码,这应该做你想要的,而不必覆盖Equals运算符