c#列表选择意外(对我而言)行为 1。var test=new List(){new foo{prop1=“1prop1”,prop2=“1prop2”},new foo{prop1=“2prop1”,prop2=“2prop2”}; 2.var test2=test.Select(x=>x.prop1=“已更改”); 3.var test3=test2.First();

c#列表选择意外(对我而言)行为 1。var test=new List(){new foo{prop1=“1prop1”,prop2=“1prop2”},new foo{prop1=“2prop1”,prop2=“2prop2”}; 2.var test2=test.Select(x=>x.prop1=“已更改”); 3.var test3=test2.First();,c#,.net,linq,C#,.net,Linq,请向我解释一下这种行为 为什么foo.prop1值在第3行之后发生变化 这与延迟执行有关。大多数linq方法延迟执行,直到实际枚举了结果的可枚举项。因此,当您运行Select语句时,它只会创建一个准备好运行相应选择器的枚举 在可枚举项上调用First时,它会对第一项运行转换,从而更改其值 这一切都假设您打算编写x.prop1=“changed”,而不是x.prop1==“changed”。前者是赋值运算符,用于设置x.prop1的值并返回设置值。后者是相等运算符,将根据它们是否相等返回布尔值。当

请向我解释一下这种行为

为什么foo.prop1值在第3行之后发生变化

这与延迟执行有关。大多数linq方法延迟执行,直到实际枚举了结果的可枚举项。因此,当您运行Select语句时,它只会创建一个准备好运行相应选择器的枚举

在可枚举项上调用
First
时,它会对第一项运行转换,从而更改其值


这一切都假设您打算编写
x.prop1=“changed”
,而不是
x.prop1==“changed”
。前者是赋值运算符,用于设置
x.prop1
的值并返回设置值。后者是相等运算符,将根据它们是否相等返回布尔值。

当您可能希望进行相等比较时,您正在进行赋值
=

1. var test = new List<foo>() { new foo { prop1 ="1prop1", prop2 = "1prop2" }, new foo { prop1 = "2prop1", prop2 = "2prop2" }  };

2. var test2 = test.Select(x => x.prop1 = "changed");

3. var test3 = test2.First();

=
是赋值,这意味着它实际上改变了值

您希望使用
==
来检查是否相等

尝试:


var test2=test。选择(x=>x.prop1
=

您希望它做什么而它没有做什么?您需要将x.prop1=“changed”更改为x.prop1=“changed”。==是一个平等的测试我真诚的道歉,但为什么你们都决定我需要把'='改成'=''?真的,为什么?“为什么值会改变?”这个问题不够清楚吗?@d.maciej 3个好答案和1条评论解释了值为什么会改变(顺便说一句,它在第2行之后改变,而不是第3行)。不仅如此,还为您提供了解决问题的解决方案。您认为我们为什么不理解您的问题?是的。延迟执行。如果第二行代码是test2=test。选择(x=>{x.prop1=changed;返回x});第三行调用了枚举器,一切都会好的。但您看到,在给定的示例中,test2将是List,准确地说,{'changed','changed'}。为什么对其调用枚举数会更改“test”的值(即列表)?我不确定是否理解您的意思。将第二行更改为您引用的内容将与第二行的操作完全相同。同样,在给定的示例中,test2的类型不是
List
,而是
IEnumerable
。为什么调用e分子更改test的值?因为这是您告诉它要做的。您使用赋值来更改prop1的值,当它迭代第一项时,它运行您告诉它的代码并更改值。
 var test2 = test.Select(x => x.prop1 == "changed");