Domanda

Ho diverse classi nella mia richiesta, che hanno tutti una proprietà Name che voglio usare come la mia base per il confronto (Distinct(), etc.). Dal momento che sto andando sempre essere il confronto su Name, ho deciso di estrarre un'interfaccia, ISomeComparedStuff, che ha semplicemente un propery Name che tutte le mie altre classi implementano. Ho creato una classe di confronto in quanto tale:

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

L'unico problema è quando provo a codice contro di esso:

public class SomeStuff : ISomeComparedStuff
{
  ...
}

public class SomeMoreStuff : ISomeComparedStuff
{
  ...
}

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

sto ottenendo un errore di cast (SomeStuff a ISomeComparedStuff). C'è qualche modo per fare questo quindi ho solo bisogno di un confronto di classe, altrimenti avrei dovuto crearne uno per ogni una delle mie classi (anche se io sono sempre andando a confrontare il Name)?

Nota: ho capito questa domanda "titolo" ha bisogno di aiuto. Qualsiasi suggerimento sarebbe grande.

È stato utile?

Soluzione

Non sono sicuro se questa è una soluzione buona o no, ma come di fare MyComparer una classe generica?

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

Unico inconveniente è che devi nuova di un versione appropriata:

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

L'espansione un po ', si potrebbe anche fare un nuovo metodo di estensione in questo modo:

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

Altri suggerimenti

Forse qualcosa di simile:

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

o utilizzare il IEqualityComparer non generico.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top