Pregunta

Tengo este

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

Me gustaría hacer esto si es que donde esté permitido

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

He intentado utilizar el genérico LambdaComparer pero desde que estoy usando tipos anónimos no hay ningún tipo de asociado con.

"Ayúdame Obi Wan Kenobi, eres mi única esperanza"

¿Fue útil?

Solución

El truco es crear un comparador que sólo funciona en los tipos inferidos. Por ejemplo:

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

Ahora puedo hacer lo siguiente ... solución hacky:

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

Otros consejos

La mayoría de las veces cuando se compara (por la igualdad o clasificación) está interesado en la elección de las claves para comparar por, no es el método de la igualdad o la comparación misma (esto es la idea detrás de la API ordenar una lista de Python).

Hay un ejemplo de teclas de la igualdad comparador aquí .

observo que la respuesta de JaredPar no acaba de responder a la pregunta ya que los métodos set como distintas y Salvo requerir una IEqualityComparer<T> no un IComparer<T>. A continuación se asume que un IEquatable tendrá un GetHashCode adecuado, y ciertamente tiene un adecuado método 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);
    }
}

Cuando la misma inferencia a partir de un truco clase estática se utiliza como en la respuesta de JaredPar.

Para ser más general que podría proporcionar dos Func s:. Un Func<T, T, bool> para comprobar la igualdad y Func<T, T, int> para seleccionar un código hash

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top