以下是一些单元测试,用于演示我们所看到的内容:
[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","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",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是否也包含对原始列表的引用?
>查询的“接收者”被视为一个值 – 它永远不会改变.如果该值是对列表的引用,则该值继续是对该列表的引用.列表的内容可能会更改,但哪个列表不会更改.
>查询子句引用的局部变量被视为变量 – 始终使用这些变量的最新值.
让我给你一个现实世界的比喻.假设你在厨房里.你有一个标有“房子”的抽屉和一个标有“名字”的抽屉.在标有“房子”的抽屉里,有一张纸上写着“宾夕法尼亚大道1600号”.在标有“名字”的抽屉里,有一张纸上写着“米歇尔”.当你说:
var house = GetHouse("1600 Pennsylvania Avenue");var name = "Michelle";var query = from resIDent in house.ResIDents where resIDent.Firstname == name select resIDent;
这就像编写查询:
"List all the resIDents of the White House whose first name is (look at the pIEce of paper in the drawer marked "name" in my kitchen)"
该查询返回的值取决于(1)居住在白宫的人,以及(2)查询运行时在纸上写的是什么名称.
这与编写查询不同:
"List all the resIDents of (look at the pIEce of paper in the drawer marked "house" in my kitchen) whose first name is (look at the pIEce of paper in the drawer marked "name" in my kitchen)"
运行查询的对象不是变量.白宫的内容可以改变.查询询问的名称可能会更改.因此,查询的结果可以通过两种方式改变 – 使用时间和名称变量的值.但是无论你对保存引用的变量做什么,查询询问的内容都不会改变.该变量与查询无关;它的值用于构建查询.
总结以上是内存溢出为你收集整理的c# – 当重新初始化源列表时,LINQ查询返回旧结果全部内容,希望文章能够帮你解决c# – 当重新初始化源列表时,LINQ查询返回旧结果所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)