Мы с коллегой обсуждали ситуацию, когда запрос IEnumerable
возвращал старое результирующее множество после повторной инициализации исходного списка. Где-то в выполнении приложения список устанавливался в нуль и повторно заполнялся новыми значениями. Сам запрос никогда не переопределялся и продолжал возвращать старые результаты. На самом деле, даже не важно, остался ли исходный список null
; старые результаты все еще возвращались.Запрос LINQ возвращает старые результаты, когда исходный список повторно инициализирован
Вот несколько модульных тестов, чтобы продемонстрировать, что мы видим:
[Test]
public void QueryResultsBasedOnCurrentListEvenAfterUpdate()
{
var list = new List<string> { "Two", "Three" };
var query = list.Where(x => x.Length > 3);
var result1 = query.ToList();
list.Clear();
list.AddRange(new List<string> { "Four", "Five", "One" });
//Correctly gets an updated result set
var result2 = query.ToList();
//PASS
CollectionAssert.AreEquivalent(new List<string> { "Three" }, result1);
//PASS
CollectionAssert.AreEquivalent(new List<string> { "Four", "Five" }, result2);
}
[Test]
public void QueryResultsBasedOnCurrentListEvenAfterSetToNullAndReInstantiated()
{
var list = new List<string> { "Two", "Three" };
var query = list.Where(x => x.Length > 3);
var result1 = query.ToList();
list = null;
list = new List<string> { "Four", "Five", "One" };
var result2 = query.ToList();
//PASS
CollectionAssert.AreEquivalent(new List<string> { "Three" }, result1);
//FAIL : result2 == result1. The query wasn't evaluated against the new list
CollectionAssert.AreEquivalent(new List<string> { "Four", "Five" }, result2);
}
[Test]
public void QueryExecutionThrowsExceptionWhenListIsSetToNull()
{
var list = new List<string> { "Two", "Three" };
var query = list.Where(x => x.Length > 3);
list = null;
//FAIL : The query is still evaluated against the original list
Assert.Throws<ArgumentNullException>(() => query.ToList());
}
кажется, что, несмотря на отложенное выполнение, эти запросы по-прежнему указывает на исходный список. Пока исходная коллекция, которая была построена против запроса, остается живой, запрос правильно оценивает результаты. Однако, если список повторно создается, запрос остается привязанным к исходному списку.
Что мне не хватает? Пожалуйста, объясните ...
UPDATE:
Я вижу такое же поведение для запроса, построенного как IQueryable
. Имеет ли ссылка IQueryable
ссылку на исходный список?
Хороший ответ. Также случай с Linq к объектам. Там уже есть материализованный список. Это не похоже на возвращение IQueryable и построение «запроса», которое еще не материализовалось. –
@ latr0dectus: Я вижу то же поведение для запроса IQueryable. – curtisthibault