ObservableCollection.Contains()不能正常工作

本文关键字:工作 常工作 不能 Contains ObservableCollection | 更新日期: 2023-09-27 18:19:06

考虑以下内容:

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

为什么将x = "a", y = "1"添加到ListView中?

如果我改变ObservableCollectionListCollection,它做同样的

ObservableCollection.Contains()不能正常工作

'Contains'方法使用了on对象的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; 
     } 
}

你的循环将访问你类中的强类型Equals方法,这将导致你想要的行为。

注意:string类也继承了T的等价类,这就是允许相等操作符对字符串的内容而不是字符串的地址进行操作的原因。

因为您已经将该值集添加到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