Pergunta

Eu tenho esta

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

Eu gostaria de fazer isso se ele onde for permitido

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

Eu tentei usar o LambdaComparer mas desde im usando tipos anônimos não há nenhum tipo associá-lo com.

"Help me Obi Wan Kenobi, você é minha única esperança"

Foi útil?

Solução

O truque é criar um comparador que só funciona em tipos inferidos. Por exemplo:

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

Agora eu posso fazer o seguinte ... solução hacky:

var comp = n.CreateComparerForElements((x, y) => x.Vchr == y.Vchr);

Outras dicas

Na maioria das vezes quando você compara (para a igualdade ou classificar) você estiver interessado em escolher as chaves para comparar por, e não a si mesmo (esta é a idéia por trás da API lista de classificação do Python) igualdade ou a comparação do método.

Há uma igualdade exemplo-chave comparer aqui .

Faço notar que a resposta de JaredPar não chega a responder a pergunta já que os métodos set Gosta distinta e, exceto exigir uma IEqualityComparer<T> não um IComparer<T>. O seguinte assume que um IEquatable terá um GetHashCode adequada, e certamente tem um método Equals adequado.

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

Quando a mesma inferência a partir de um truque classe estática é usada como na resposta de JaredPar.

Para ser mais geral, você poderia fornecer duas Funcs:. Um Func<T, T, bool> para verificar igualdade e Func<T, T, int> para selecionar um código hash

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top