ObservableCollection.Contains()无法正常工作

时间:2011-12-31 20:03:15

标签: c# .net wpf vb.net

请考虑以下事项:

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

如果我将ObservableCollection更改为ListCollection,则会执行相同操作。

4 个答案:

答案 0 :(得分:18)

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

考虑将您的班级更改为此...

 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方法,这将导致您所追求的行为。

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

答案 1 :(得分:3)

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

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

和CY:

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

这些是不同的对象。

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)