1

Why does aFooList contain five copies of the last item, instead of the five items I inserted?

Expected Output: 01234

Actual Output: 44444

using System;
using System.Collections.Generic;

namespace myTestConsole {
    public class foo {
        public int bar;
    }

    class Program {
        static void Main(string[] args) {
            foo aFoo = new foo(); // Make a foo
            List<foo> aFooList = new List<foo>(); // Make a foo list

            for (int i = 0; i<5; i++) { 
                aFoo.bar = i;
                aFooList.Add(aFoo);
            }

            for (int i = 0; i<5; i++) {
                Console.Write(aFooList[i].bar);
            }
        }
    }
}
Steven
  • 13,501
  • 27
  • 102
  • 146

4 Answers4

4

You have added the same item, aFoo, 5 times. When you modify contents of a reference-type object you don't create new copies, you modify the same object.

wRAR
  • 25,009
  • 4
  • 84
  • 97
2
List<foo> aFooList = new List<foo>(); // Make a foo list

for (int i = 0; i<5; i++) { 
    foo aFoo = new foo(); // Make a foo
    aFoo.bar = i;
    aFooList.Add(aFoo);
}

You are still modifying your aFoo while it is in the list.

Brad M
  • 7,857
  • 1
  • 23
  • 40
0

Your variable 'aFoo' is basically a pointer to a location in memory. Without "newing" up another instance (malloc) you're modifying the same location in memory and add the same pointer 5 times.

The "new" keyword fullfills the function as far as programmers are concerned in C# as malloc does in C. It will get a new memory location and make aFoo point to that location, instead of the old one.

From MSDN:

The new operator is used to create objects and invoke constructors

MSDN

Alexander Matusiak
  • 1,748
  • 2
  • 18
  • 29
0

You've added a reference to the same object to your list 5 times, each time modify the value of bar. Add this line after aFooList.Add(aFoo); to see the effect each time you add a foo to the list.

Console.WriteLine(string.Join("", foos.Select(f => f.bar)));

For what it's worth, it's a one-liner (spaced nicely for readability) with Linq.

var foos = Enumerable.Range(0, 5)
                     .Select(n => new foo {bar = n})
                     .ToList();

Complete example:

foo aFoo = new foo(); // Make a foo
List<foo> aFooList = new List<foo>(); // Make a foo list
Console.WriteLine("\nUsing aFooList");
for (int i = 0; i < 5; i++)
{
    aFoo.bar = i;
    aFooList.Add(aFoo);
    Console.WriteLine(string.Join("", aFooList.Select(f => f.bar)));
}

var foos = Enumerable.Range(0, 5).Select(n => new foo { bar = n }).ToList();
Console.WriteLine("\nUsing foos");
Console.WriteLine(string.Join("", foos.Select(f => f.bar)));

Console.ReadLine();

Output:

Using aFooList
0
11
222
3333
44444

Using foos
01234
Austin Salonen
  • 49,173
  • 15
  • 109
  • 139