2011-12-31 46 views
5

は、次の点を考慮ObservableCollection.Contains()は正常に動作しない

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

なぜそれがListViewx = "a", y = "1"を追加しますか?

ObservableCollectionListまたはCollectionに変更すると、同じことが行われます。

答えて

18

'Contains'メソッドは、オブジェクト上のEqualsを使用します。これは、メモリアドレスが異なることを単純にチェックします。

はこれにあなたのクラスを変更することを検討...

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

あなたのループは強く、あなたのクラスのメソッドに等しく、これはあなたが後にしている動作が発生します型付けを訪問します。

注:文字列クラスALSOはTのIEquatableを継承しているため、文字列のアドレスではなく文字列の内容を操作することができます。

2

"a" != "a"です。少なくとも、必ずしもそうではありません。

Contains()は、実際の内容ではなくメモリアドレスをチェックします。同じオブジェクトを2回挿入することはできません。"a"は、"a"と同じオブジェクトではありません(少なくともここにはありません)。あなたが比較演算について知らせるべき

+0

私はおそらくすべての値を繰り返し、それらが等しいかどうかをチェックします。しかし、私はC#プログラマーではないので、もっと簡単な方法があるかもしれません。 –

3

そのあなたは値がCXに設定することを追加したので:

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

とCYへ:

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

そして、それらは異なるオブジェクトです。

特定のキーが存在するかどうかを確認するには、辞書に変更するか、Linqを使用する必要があります。

関連する問題