有时在foreach循环中修改属性时,更改不会保留

时间:2018-02-08 18:30:04

标签: c# linq

有时,当循环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;
    }
}

这是某种错误,还是我在做一些我不应该做的事情?

1 个答案:

答案 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()