1
namespace ConsoleApplication4
{
    class T1
    {
        public int MyProperty { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var tmp = (new[] { 1, 3, 4 }).Select(x =>new T1 { MyProperty=x});
            foreach (var s in tmp)
            {
                s.MyProperty = 9;
            }
            foreach (var s in tmp)
            {
                Console.WriteLine(s.MyProperty);
            }
            Console.ReadLine();
        }
    }
}

I expect there are three 9 on screen, but the values are still same.

However, if I modify code a little bit, the values would be changed successfully i.e. :

var tmp = (new[] { 1, 3, 4 }).Select(x =>new T1 { MyProperty=x}).ToList();

I wonder why?

Alina Anjum
  • 1,178
  • 6
  • 30
  • 53
Netsphere Wu
  • 45
  • 1
  • 7
  • 1
    you should read about [IEnumerable vs List in c#](http://stackoverflow.com/questions/3628425/ienumerable-vs-list-what-to-use-how-do-they-work) – Nikola.Lukovic Jun 27 '16 at 09:01

1 Answers1

6

The reason is deferred execution.

tmp is not a list or an array. It's only a definition how to create the enumeration. Or in other words: tmp is only the question, but not the answer.

So in the second foreach, the enumerator created by the Select is executed again, creating new instances of T1.

When you use .ToList() instead, the enumeration is converted to a List (so tmp is a List<T1>). And you can iterate that List as often as you want without creating new instances.

René Vogt
  • 43,056
  • 14
  • 77
  • 99