2011-12-31 27 views
5

Si consideri il seguente:ObservableCollection.Contains() non funziona correttamente

class Bind 
{ 
    public string x { get; set; } 
    public string y { get; set; } 
} 
public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     ObservableCollection<Bind> cX = new ObservableCollection<Bind>(); 
     ObservableCollection<Bind> cY = new ObservableCollection<Bind>(); 
     cX.Add(new Bind { x = "a", y = "1" }); 
     cX.Add(new Bind { x = "b", y = "2" }); 
     cY.Add(new Bind { x = "a", y = "1" }); 
     foreach (var i in cX) 
     { 
      if (!cY.Contains(i)) { lv.Items.Add(i); } //lv is a ListView control 
     } 
    } 
} 

Perché si aggiunge x = "a", y = "1" al ListView?

Se cambio ObservableCollection a List o Collection, fa lo stesso.

risposta

18

Il metodo "Contiene" utilizza l'oggetto Uguale sull'oggetto e questo semplicemente controlla che gli indirizzi di memoria siano diversi.

pensare di cambiare la tua classe a questo ...

class Bind : IEquatable<Bind> { 
    public string x { get; set; } 
    public string y { get; set; } 
    public bool Equals(Bind other) 
    { 
     return x == other.x && y == other.y; 
    } 
} 

il ciclo sarà quindi visitare il metodo Equals fortemente tipizzato nella classe, e questo si tradurrà nel comportamento siete dopo.

NOTA: la stringa di classe ALSO eredita da IEquatable di T e questo è ciò che consente all'operatore di uguaglianza di operare sul contenuto della stringa anziché sull'indirizzo della stringa.

2

Perché "a" != "a". Almeno, non sempre.

Contains() controllerà gli indirizzi di memoria, non i contenuti effettivi. Non è possibile inserire lo stesso oggetto due volte e "a" non è lo stesso oggetto di "a" (almeno non qui).

+0

Probabilmente eseguirò l'iterazione di tutti i valori e verificherò se sono uguali. Ma io non sono un programmatore C#, quindi potrebbe esserci un modo più semplice. –

3

Perché questo si è aggiunto che il valore impostato su CX:

cX.Add(new Bind { x = "a", y = "1" }); 

ea CY:

cY.Add(new Bind { x = "a", y = "1" }); 

E questi sono oggetti diversi.

Se si desidera verificare se è presente una determinata chiave, sarà necessario passare a un dizionario o utilizzare Linq.

Problemi correlati