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 cX = new ObservableCollection(); ObservableCollection cY = new ObservableCollection(); 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 } } } 

为什么在ListView添加x = "a", y = "1"

如果我将ObservableCollection更改为ListCollection ,它也会这样做。

‘Contains’方法使用Equals on对象,这只是检查内存地址是否不同。

考虑将您的class级改为此…

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

然后,您的循环将访问类中强类型的Equals方法,这将导致您所处的行为。

注意:字符串类ALSOinheritance自T的IEquatable,这允许相等运算符对字符串的内容而不是字符串的地址进行操作。

因为您已将该值设置为CX:

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

和CY:

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

那些是不同的对象。

如果要查看是否存在给定密钥,则需要更改为字典或使用Linq。

因为"a" != "a" 。 至少,并非总是如此。

Contains()将检查内存地址,而不是实际内容。 你不能两次插入同一个对象, "a""a"不是同一个对象(至少,不是这里)。

您应该告知有关比较器:

“使用默认的相等比较器Default将元素与指定值进行比较。”

在EqualityComparer.Default属性中,您可以看到一个示例。