有时,当循环LINQ返回的Enumerable并修改其中元素的属性时,更改会在foreach循环之外丢失。到目前为止,只有在使用.Select()创建枚举时才会注意到它,然后才会在Select中创建一个新对象。
using System;
using System.Collections.Generic;
using System.Linq;
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
var collection1 = new List<TestClass>();
collection1.Add(new TestClass() { Property = "initial" });
collection1.Add(new TestClass() { Property = "initial" });
var collection2 = new List<TestClass>();
collection2.Add(new TestClass() { Property = "initial" });
collection2.Add(new TestClass() { Property = "initial" });
var enumerable1 = collection1.Select(x => x);
var enumerable2 = collection2.Select(x => new TestClass() { Property = x.Property });
foreach(var element in enumerable1)
{
element.Property = "new";
}
Console.WriteLine(enumerable1.First().Property); //outputs "new"
foreach (var element in enumerable2)
{
element.Property = "new";
}
Console.WriteLine(enumerable2.First().Property); //outputs "initial"
}
}
class TestClass
{
public string Property;
}
}
这是某种错误,还是我在做一些我不应该做的事情?
答案 0 :(得分:2)
这里发生了什么:
myTable
您正在评估表达式:
myTable[1]()
然后使用此foreach (var element in enumerable2)
{
element.Property = "new";
}
,您再次评估表达式。除非您在表达式上调用collection2.Select(x => new TestClass() { Property = x.Property })
,否则将再次重新计算表达式。你所拥有的在功能上等同于:
enumerable2.First().Property
看看发生了什么?要解决此问题,请在您的ToList()
声明中致电foreach (var element in collection2.Select(x => new TestClass() { Property = x.Property }))
{
element.Property = "new";
}
Console.WriteLine(collection2.Select(x => new TestClass() { Property = x.Property }).First().Property)
:
ToList()