Вопрос по linq – IEqualityComparer для анонимного типа

31

у меня есть это

 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 но так как я использую анонимные типы, нет типа связать его с.

"Помоги мне, Оби Ван Кеноби, ты моя единственная надежда"

Это может помочьWrap a delegate in an IEqualityComparer marbel82
Отличный вопрос, я просто искал то же самое. Невероятно, это не в стандартной библиотеке. orip

Ваш Ответ

3   ответа
3

когда вы сравниваете (для равенства или сортировки), вас интересует выбор ключей для сравнения, а не сам метод равенства или сравнения (это идея API сортировки списка Python).

Вот пример компаратора равенства ключейВот.

0

что ответ JaredPar не совсем отвечает на вопрос, поскольку для таких методов набора, как Distinct и Except, требуетсяIEqualityComparer<T> не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> выбрать хэш-код.

Error: User Rate Limit Exceeded
17

чтобы создать компаратор, который работает только на выведенных типах. Например:

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);
  }
}

Теперь я могу сделать следующее ... хакерское решение:

var comp = n.CreateComparerForElements((x, y) => x.Vchr == y.Vchr);
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded kjgilla

Похожие вопросы