Это правильное поведение ObservableCollection и Linq? - PullRequest
0 голосов
/ 30 марта 2011

Привет, я только что столкнулся с проблемой синхронизации и повторил ее в этом небольшом примере.

class MyClass
    {
        public int Number { get; set; }
    }

static void Main(string[] args)
        {
            var list = new ObservableCollection<MyClass>
                           {
                               new MyClass() {Number = 1},
                               new MyClass() {Number = 2},
                               new MyClass() {Number = 3}
                           };

            var count = from i in list where i.Number == 1 select i;
            Console.WriteLine("Found {0}", count.Count());

            list[2].Number = 1;
            Console.WriteLine("Found {0}", count.Count());
        }

Это выдаст

Found 1
Found 2

Это не то, что я ожидал,Я догадался, он вернется 1 оба раза.В любом случае, чтобы избежать этого действия и по-прежнему использовать наблюдаемую коллекцию?

Я пытаюсь реализовать метод переупорядочения, но это затрудняет выбор правильного элемента.

ОБНОВЛЕНИЕ

Простым решением, конечно, было бы изменить его следующим образом

int found = count.Count();
            Console.WriteLine("Found {0}", found);

            list[2].Number = 1;
            Console.WriteLine("Found {0}", found);

Ответы [ 2 ]

3 голосов
/ 30 марта 2011

Это связано с ленивой оценкой вашего запроса LINQ и не имеет ничего общего с ObservableCollection. Если вы измените свой запрос LINQ на следующую строку:

(from i in list where i.Number == 1 select i).ToList();

вы увидите ожидаемое поведение.

Добавление ToList() гарантирует, что ваш запрос LINQ будет оценен в данный момент. В противном случае он оценивается только при необходимости. Поскольку вы вызываете Count() дважды, запрос оценивается дважды, но по другим данным.

2 голосов
/ 30 марта 2011

Вы столкнулись с одной из ловушек LINQ. Переменная count в вашем примере не является результатом запроса, она является запросом. Каждый раз, когда вы что-то меняете в основной коллекции, это изменение будет отражено в последующих вызовах.

...