奇怪的行为:向ObservableCollection添加了对象

时间:2015-08-19 13:28:23

标签: c# .net

将对象添加到ObservableCollection然后查找它时,我有一种奇怪的行为。刚添加之后就找到了,然后使用相同的代码就不再了?

public class TestClass {
    public TestClass(string s) {
        Str = s;
    }

    public string Str {
        get;
        set;
    }
}

    private ObservableCollection<TestClass> testCollection = new ObservableCollection<TestClass>();
    private List<string> newValueList = new List<string> { "one", "two", "three" };

private void Test() {
    var tmpList = newValueList.Select(p => new TestClass(p));

    foreach (var v in tmpList) {
        testCollection.Add(v);
        if (testCollection.Contains(v))
            Console.WriteLine("YES");
        else
            Console.WriteLine("NO");
    }

    foreach (var v in tmpList) {
        if (testCollection.Contains(v))
            Console.WriteLine("IN");
        else 
            Console.WriteLine("OUT");
    }
}

运行此代码将导致输出:YES YES YES OUT OUT OUT

使用 .ToList() tmpList时,您将获得预期的结果。

3 个答案:

答案 0 :(得分:2)

您定义了一个运行时不知道如何比较它们的类。所以它假设当它们具有相同的引用而不是Str时,它们中的两个是相等的。换句话说,当TestClassa是相同的地址时,bab)的两个对象是相等的。如果您想要更改此设置并使ab相等Str,则应覆盖EqualsGetHashCodeYou can read more hereherehere

第一部分:

foreach (var v in tmpList) {
    testCollection.Add(v);
    if (testCollection.Contains(v))
        Console.WriteLine("YES");
    else
        Console.WriteLine("NO");
}

在这里,您要将v添加到集合中并检查其中是否有v,因此它将返回“是”。

第二部分

foreach (var v in tmpList) {
    if (testCollection.Contains(v))
        Console.WriteLine("IN");
    else 
        Console.WriteLine("OUT");
}

这里你正在寻找v(这不是你的集合中对象的完全相同的引用(因为懒惰的评估每次都在foreach迭代中生成新的实例))你的集合中它将返回“OUT”!

答案 1 :(得分:1)

问题是tmpList不是一个列表,而是一个&#34;懒惰的&#34;每次foreach时都会创建新对象的迭代器。

纠正这条线:

var tmpList = newValueList.Select(p => new TestClass(p)).ToList();

答案 2 :(得分:1)

Select方法返回一个IEnumerable对象,该对象在循环中使用时调用GetEnumerator,因此在列表中的每个元素的select方法中为两个循环分别调用Lambda。

Loop1:选择(p =&gt; new TestClass(p)) Loop2:选择(p =&gt; new TestClass(p))

所以只要循环使用tmpList 对于两个循环,执行select语句,调用lambda

因此为每个循环创建了不同的对象集。

您可以通过在lambda表达式中创建断点来验证此行为。

你会看到它被叫6次而不是3次。