2011-12-31 58 views
5

xem xét như sau:ObservableCollection.Contains() không hoạt động đúng

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

Tại sao nó thêm x = "a", y = "1" đến ListView?

Nếu tôi thay đổi ObservableCollection thành List hoặc Collection, thì cũng vậy.

Trả lời

18

Phương pháp 'Chứa' sử dụng đối tượng Bình đẳng trên đối tượng, và điều này chỉ đơn giản kiểm tra xem địa chỉ bộ nhớ có khác nhau không.

xem xét thay đổi lớp học của bạn để này ...

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

vòng lặp của bạn sau đó sẽ ghé thăm các phương pháp mạnh mẽ gõ Equals trong lớp học của bạn, và điều này sẽ dẫn đến hành vi mà bạn đang theo đuổi.

LƯU Ý: lớp chuỗi ALSO kế thừa từ IEquatable của T và đó là những gì cho phép toán tử bình đẳng hoạt động trên nội dung của chuỗi chứ không phải là địa chỉ của chuỗi.

2

"a" != "a". Ít nhất, không phải lúc nào.

Contains() sẽ kiểm tra địa chỉ bộ nhớ, chứ không phải nội dung thực tế. Bạn không thể chèn cùng một đối tượng hai lần và "a" không phải là đối tượng giống như "a" (ít nhất, không có ở đây).

+0

Tôi có thể lặp qua tất cả các giá trị và kiểm tra xem chúng có bình đẳng không. Nhưng tôi không phải là lập trình viên C#, vì vậy có thể có một cách dễ dàng hơn. –

3

Bởi vì bạn đã nói thêm rằng giá trị thiết lập để CX:

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

và CY:

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

Và đó là những đối tượng khác nhau.

Nếu bạn muốn xem liệu có một khóa nhất định hay không, bạn sẽ cần phải thay đổi sang từ điển hoặc sử dụng LINQ.

Các vấn đề liên quan