2013-05-29 14 views
10

Elenco1 contiene elementi {A, B} e Elenco2 contiene elementi {A, B, C}.Utilizzo di Linq Tranne che non funziona come ho pensato

Quello che mi serve è quello di essere restituito {C} quando uso l'estensione Exq di Linq. Invece mi vengono restituiti {A, B} e se capovolgo gli elenchi nella mia espressione il risultato è {A, B, C}.

Sto fraintendendo il punto di Eccezione? C'è un'altra estensione che non vedo di usare?

Ho esaminato e tentato un numero di post diversi su questo argomento senza successo fino ad ora.

var except = List1.Except(List2); //This is the line I have thus far

EDIT: Sì stavo confrontando oggetti semplici. Non ho mai usato IEqualityComparer, è stato interessante conoscere.

Grazie a tutti per l'aiuto. Il problema non stava implementando il comparatore. Il post del blog collegato e l'esempio sotto dove è utile.

+1

Cosa c'è esattamente in queste liste? –

+0

Qual è il tipo di dati dei tuoi articoli. È una lezione? Questo link potrebbe aiutarti http://stackoverflow.com/questions/1645891/why-isnt-except-linq-comparing-things-properly-using-iequatable – arunlalam

+0

Sono oggetti semplici con un paio di proprietà per il momento. Guarderò attraverso il tuo link. – Schanckopotamus

risposta

10

Se si memorizzano i tipi di riferimento nell'elenco, è necessario assicurarsi che vi sia un modo per confrontare gli oggetti per l'uguaglianza. Altrimenti verranno controllati confrontando se si riferiscono allo stesso indirizzo.

È possibile implementare IEqualityComparer<T> e inviarlo come parametro alla funzione Except(). Ecco un blog post che potresti trovare utile.

+0

Per essere chiari questa è la soluzione che ha risolto il mio problema molto tempo fa ed è un'opzione valida, a seconda dello scenario. – Schanckopotamus

6

Hai semplicemente confuso l'ordine degli argomenti. Posso vedere dove questa confusione nata, perché il official documentation non è stato utile potrebbe essere:

Produce la differenza di set di due sequenze utilizzando l'operatore di confronto uguaglianze predefinito per confrontare i valori.

meno che non stai versati nella teoria degli insiemi, potrebbe non essere chiaro ciò che un set difference in realtà è — non è semplicemente ciò che è diverso tra i set. In realtà, Except restituisce l'elenco di elementi nel primo set che non si trovano nel secondo set.

Prova questo:

var except = List2.Except(List1); // { C } 
+0

Se si modifica l'ordine dell'elenco, si ottiene {A, B, C} – Schanckopotamus

4

Quindi, solo per completezza ...

// Except gives you the items in the first set but not the second 
    var InList1ButNotList2 = List1.Except(List2); 
    var InList2ButNotList1 = List2.Except(List1); 
// Intersect gives you the items that are common to both lists  
    var InBothLists = List1.Intersect(List2); 

Edit: Dato che le vostre liste contengono oggetti è necessario passare in un IEqualityComparer per la classe ... Qui è quello che sarà il tuo eccetto con un campione IEqualityComparer basato su oggetti inventati ... :)

// Except gives you the items in the first set but not the second 
     var equalityComparer = new MyClassEqualityComparer(); 
     var InList1ButNotList2 = List1.Except(List2, equalityComparer); 
     var InList2ButNotList1 = List2.Except(List1, equalityComparer); 
// Intersect gives you the items that are common to both lists  
     var InBothLists = List1.Intersect(List2); 

public class MyClass 
{ 
    public int i; 
    public int j; 
} 

class MyClassEqualityComparer : IEqualityComparer<MyClass> 
{ 
    public bool Equals(MyClass x, MyClass y) 
    { 
     return x.i == y.i && 
       x.j == y.j; 
    } 

    public int GetHashCode(MyClass obj) 
    { 
     unchecked 
     { 
      if (obj == null) 
       return 0; 
      int hashCode = obj.i.GetHashCode(); 
      hashCode = (hashCode * 397)^obj.i.GetHashCode(); 
      return hashCode; 
     } 
    } 
} 
+0

InList1ButNotList2 restituisce {C, B, A}, che è ciò che è successo. – Schanckopotamus

+0

@Schanckopotomus Ahh ... le tue liste sono oggetti e le loro proprietà sono uguali ma gli oggetti non sono di riferimento uguali giusto? – Kevin

Problemi correlati