List<Person> persons = new List<Person>() {
new Person(){ ID=1,Name="bbb", Age=1},
new Person() { ID = 1, Name = "aaaa", Age = 2 }
};
persons.Where(o =>
{
if (o.Age == 1 && o.Name == "bbb")
{
o.Name += "HEHE";
return true;
}
else
return false;
});
//1 bbb 1
//1 aaa 2
persons.Where(o =>
{
if (o.Age == 1 && o.Name == "bbb")
{
o.Name += "HEHE";
return true;
}
else
return false;
}).Tolist();
//--ToList()后
//1 bbbHEHE 1
//1 aaa 2
谁详细的说下,为什么会出现这种情况,不加tolist persons里面的名字没加HEHE,Tolist之后就加上了HEHE..好奇怪啊
楼主的第一个结果是如何输出的?
如果仅仅是调用了Where方法后,在编译器中看persons变量值是不会变的,因为这个是延迟查询,你的那句属性赋值操作没有真正执行。
查考:https://msdn.microsoft.com/zh-cn/library/bb534803(v=vs.110).aspx
第二个查询调用ToList方法,查询被执行了,persons变量内容被改变。
查考:https://msdn.microsoft.com/zh-cn/library/bb342261(v=vs.110).aspx
理解延迟查询和直接查询请查考:https://msdn.microsoft.com/zh-cn/library/bb397906.aspx
再看下源代码:
你的
o => { if (o.Age == 1 && o.Name == "bbb") { o.Name += "HEHE"; return true; } else return false; }
就是predicate,只是作为参数传过去了,没有立即执行。
请参考:http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,e73922753675387a
很全面谢谢,你是个很认真的人。
第一个结果是我在编译器中查看的,被你说中了 嘿嘿
1、ToList
will create a new list, but because in this case Person is a reference type then the new list will contain references to the same objects as the original list.
2、so ....
For your first linq query, it is ok, but can not update value. if you want to update value, should be something like,
persons.Where(o => o.Age == 1 && o.Name == "bbb").ToList().ForEach(c=>c.Name+="HEHE");
我可以这样理解你上面的代码吗,where之后筛选出来了我要的数据,然后再去foreach循环去修改+=Name,因为是引用类型,所以直接修改会改变本来的persons里面的对象的值.
还有你这种where之后foreach 的效率和我写的lamda表达式的方式哪个更好一点呢, 我的代码是where的时候查了一遍后面就不用再foreach了。
@伦敦总依恋雨点: 不可以在Where里面修改的,你这个写法太诡异了。
1楼正解。学习了
ToList之后,直接返回结果集,是定集。不ToList,那么返回的是表达式,如果persons在之后变化了,那么结果也会在变化后的persons中去筛选。