2011-12-31 28 views
5

en cuenta lo siguiente:ObservableCollection.Contains() no funciona correctamente

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

¿Por qué añadir a la x = "a", y = "1"ListView?

Si cambio ObservableCollection a o Collection, hace lo mismo.

Respuesta

18

El método 'Contiene' utiliza el objeto Igual en, y esto simplemente comprueba que las direcciones de memoria son diferentes.

considere cambiar su clase a este ...

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

Su bucle a continuación, visite el método inflexible de tipos iguales en su clase, y esto dará como resultado el comportamiento que está después.

NOTA: la clase de cadena TAMBIÉN hereda de IEtabletable of T y eso es lo que permite al operador de igualdad operar el contenido de la cadena en lugar de la dirección de la cadena.

2

Porque "a" != "a". Al menos, no siempre.

Contains() comprobará las direcciones de la memoria, no los contenidos reales. No puede insertar el mismo objeto dos veces, y "a" no es el mismo objeto que "a" (al menos, no aquí).

+0

Probablemente recorra todos los valores y verifique si son iguales. Pero no soy un programador de C#, por lo que podría haber una manera más fácil. –

3

Debido a que ha agregado que el valor ajustado en CX:

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

y CY:

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

Y esos son diferentes objetos.

Si desea ver si una clave determinada está presente, tendrá que cambiar a un diccionario o utilizar Linq.

Cuestiones relacionadas