33

我有这个

 var n = ItemList.Select(s => new { s.Vchr, s.Id, s.Ctr, s.Vendor, s.Description, s.Invoice }).ToList();
 n.AddRange(OtherList.Select(s => new { s.Vchr, s.Id, s.Ctr, s.Vendor, s.Description, s.Invoice }).ToList(););

如果允许,我想这样做

n = n.Distinct((x, y) => x.Vchr == y.Vchr)).ToList();

我尝试使用通用LambdaComparer,但由于我使用匿名类型,因此没有与之关联的类型。

“帮帮我欧比旺克诺比,你是我唯一的希望”

4

3 回答 3

19

诀窍是创建一个仅适用于推断类型的比较器。例如:

public class Comparer<T> : IComparer<T> {
  private Func<T,T,int> _func;
  public Comparer(Func<T,T,int> func) {
    _func = func;
  }
  public int Compare(T x,  T y ) {
    return _func(x,y);
  }
}

public static class Comparer {
  public static Comparer<T> Create<T>(Func<T,T,int> func){ 
    return new Comparer<T>(func);
  }
  public static Comparer<T> CreateComparerForElements<T>(this IEnumerable<T> enumerable, Func<T,T,int> func) {
    return new Comparer<T>(func);
  }
}

现在我可以做以下...... hacky解决方案:

var comp = n.CreateComparerForElements((x, y) => x.Vchr == y.Vchr);
于 2009-07-01T22:17:19.790 回答
3

大多数时候,当您比较(相等或排序)时,您感兴趣的是选择要比较的键,而不是相等或比较方法本身(这是 Python 列表排序 API 背后的想法)。

这里有一个示例键相等比较器。

于 2009-08-06T14:56:44.137 回答
1

我注意到 JaredPar 的回答并没有完全回答这个问题,因为像 Distinct 和 except 这样的设置方法需要一个IEqualityComparer<T>not IComparer<T>。下面假设一个 IEquatable 将有一个合适的 GetHashCode,它当然有一个合适的 Equals 方法。

public class GeneralComparer<T, TEquatable> : IEqualityComparer<T>
{
    private readonly Func<T, IEquatable<TEquatable>> equatableSelector;

    public GeneralComparer(Func<T, IEquatable<TEquatable>> equatableSelector)
    {
        this.equatableSelector = equatableSelector;
    }

    public bool Equals(T x, T y)
    {
        return equatableSelector.Invoke(x).Equals(equatableSelector.Invoke(y));
    }

    public int GetHashCode(T x)
    {
        return equatableSelector(x).GetHashCode();
    }
}

public static class GeneralComparer
{
    public static GeneralComparer<T, TEquatable> Create<T, TEquatable>(Func<T, TEquatable> equatableSelector)
    {
        return new GeneralComparer<T, TEquatable>(equatableSelector);
    }
}

在 JaredPar 的回答中使用了来自静态类技巧的相同推理。

更笼统地说,您可以提供两个Funcs:aFunc<T, T, bool>来检查相等性和Func<T, T, int>选择哈希码。

于 2011-05-31T16:19:24.920 回答