Мы с коллегой обсуждали ситуацию, когда запрос IEnumerable
возвращал старый набор результатов после повторной инициализации списка источников.Где-то при выполнении приложения список устанавливался в нуль и пополнялся новыми значениями.Сам запрос никогда не был переопределен и продолжал возвращать старые результаты.На самом деле, даже не имело значения, остался ли список источников null
;старые результаты все еще возвращались.
Вот несколько модульных тестов, чтобы продемонстрировать, что мы видим:
[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());
}
Кажется, что, несмотря на отложенное выполнение, эти запросы все еще указывают на исходный список,Пока исходная коллекция, к которой был построен запрос, остается активной, запрос правильно оценивает результаты.Однако, если список создается заново, запрос остается привязанным к исходному списку.
Чего мне не хватает?Пожалуйста, объясните ...
ОБНОВЛЕНИЕ:
Я наблюдаю то же поведение для запроса, построенного как IQueryable
.IQueryable
также содержит ссылку на исходный список?