独特()与lambda?

对,所以我有一个枚举并希望从中获得不同的值。

使用System.Linq ,当然有一个名为Distinct的扩展方法。 在简单情况下,它可以不带参数使用,如:

var distinctValues = myStringList.Distinct();

那么好,但如果我有一个我需要指定相等的对象的枚举,唯一可用的重载是:

var distinctValues = myCustomerList.Distinct(someEqualityComparer);

相等比较器参数必须是IEqualityComparer<T>的实例。 当然,我可以做到这一点,但它有点冗长,而且很滑稽。

我所期望的是一个需要lambda的重载,比如Func <T,T,bool>:

var distinctValues
    = myCustomerList.Distinct((c1, c2) => c1.CustomerId == c2.CustomerId);

任何人都知道是否存在这样的扩展,或者一些等效的解决方法? 或者我错过了什么?

或者,有没有一种方法来指定一个IEqualityComparer内联(不容我)?

更新

我发现了Anders Hejlsberg在MSDN论坛上发布的关于此主题的回复。 他说:

你将要遇到的问题是,当两个对象比较相等时,它们必须具有相同的GetHashCode返回值(否则Distinct内部使用的哈希表将无法正常工作)。 我们使用IEqualityComparer,因为它将Equals和GetHashCode的兼容实现打包到一个接口中。

我想这是有道理的..


IEnumerable<Customer> filteredList = originalList
  .GroupBy(customer => customer.CustomerId)
  .Select(group => group.First());

它看起来像你想从MoreLINQ DistinctBy 。 然后你可以写:

var distinctValues = myCustomerList.DistinctBy(c => c.CustomerId);

以下是DistinctBy的缩减版本(无空值检查,无法指定您自己的键比较器):

public static IEnumerable<TSource> DistinctBy<TSource, TKey>
     (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    HashSet<TKey> knownKeys = new HashSet<TKey>();
    foreach (TSource element in source)
    {
        if (knownKeys.Add(keySelector(element)))
        {
            yield return element;
        }
    }
}

不,没有这样的扩展方法过载。 过去我发现自己很沮丧,因此我通常会写一个帮助类来处理这个问题。 目标是将Func<T,T,bool>IEqualityComparer<T,T>

public class EqualityFactory {
  private sealed class Impl<T> : IEqualityComparer<T,T> {
    private Func<T,T,bool> m_del;
    private IEqualityComparer<T> m_comp;
    public Impl(Func<T,T,bool> del) { 
      m_del = del;
      m_comp = EqualityComparer<T>.Default;
    }
    public bool Equals(T left, T right) {
      return m_del(left, right);
    } 
    public int GetHashCode(T value) {
      return m_comp.GetHashCode(value);
    }
  }
  public static IEqualityComparer<T,T> Create<T>(Func<T,T,bool> del) {
    return new Impl<T>(del);
  }
}

这使您可以编写以下内容

var distinctValues = myCustomerList
  .Distinct(EqualityFactory.Create((c1, c2) => c1.CustomerId == c2.CustomerId));
链接地址: http://www.djcxy.com/p/14949.html

上一篇: Distinct() with lambda?

下一篇: How should documentation refer to the plural of a type name?