Pregunta

Tengo varias clases en mi solicitud, todos los cuales tienen una propiedad Name que quiero usar como mi base de comparación (Distinct(), etc.). Ya que siempre voy a estar comparando el Name, decidí extraer una interfaz, ISomeComparedStuff, que simplemente tiene un hotel fenomenal Name que todas mis otras clases implementan. He creado una clase de comparación como por ejemplo:

public class MyComparer : IEqualityComparer<ISomeComparedStuff>
{
     public bool Equals(ISomeComparedStuff x, ISomeComparedStuff y)
     {
          return x.Name == y.Name;
     }

     public int GetHashCode(ISomeComparedStuff obj)
     {
          return obj.Name.GetHashCode();
     }
}

El único problema es cuando trato de código en contra de ella:

public class SomeStuff : ISomeComparedStuff
{
  ...
}

public class SomeMoreStuff : ISomeComparedStuff
{
  ...
}

var someStuff = GetSomeStuff().Distinct(new MyComparer);
var someMoreStuff = GetSomeMoreStuff().Distinct(new MyComparer);

Estoy recibiendo un error de reparto (SomeStuff a ISomeComparedStuff). ¿Hay alguna manera de hacer esto, así que sólo necesito uno compara la clase, de lo contrario tendría que crear uno para cada una de mis clases (a pesar de que siempre voy a comparar el Name)?

Nota: entiendo esta pregunta "título" necesita ayuda. Cualquier sugerencia sería grande.

¿Fue útil?

Solución

No estoy seguro si esto es una solución buena o no, pero ¿qué hacer MyComparer una clase genérica?

public class MyComparer<T> : IEqualityComparer<T>
    where T: ISomeComparedStuff
{
     public bool Equals(T x, T y)
     {
      return x.Name == y.Name;
     }

     public int GetHashCode(T obj)
     {
      return obj.Name.GetHashCode();
     }
}

Lo malo es que hay que nuevo hasta una versión apropiada:

var someStuff = GetSomeStuff().Distinct(new MyComparer<SomeStuff>());
var someMoreStuff = GetSomeMoreStuff().Distinct(new MyComparer<SomeMoreStuff>());

La expansión un poco, podría también hacer un nuevo método de extensión de esta manera:

public static IEnumerable<T> DistinctByName<T>(this IEnumerable<T> values)
    where T: ISomeComparedStuff
{
    return values.Distinct(new MyComparer<T>());
}

Otros consejos

Tal vez algo como:

var someStuff = GetSomeStuff().Cast<ISomeComparedStuff>().Distinct(new MyComparer);

O utilizar el IEqualityComparer no genérico.

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