-1

I'm trying to create a list and insert values in to it. But when I add a new item it changes all existing items in the list to the same value I add and I don't understand why.

Here is my code:

public List<Times> CreateListOfTimes()
{
    var listOfTimes = new List<Times>();
    var times = new Times();
    int startTime = 8;
    int endTime = startTime + 1;
    for (int i = 0; i < 8; i++)
    {
        times.StartTime = startTime;
        times.EndTime = endTime;
        listOfTimes.Add(times);
        startTime++;
        endTime++;
    }
    return listOfTimes;
}

The first time I add a value to times, times.StartTime = 8 and times.EndTime = 9. When I loop the second time I add 9 and 10 but i also change the already added 8 and 9 to 9 and 10. Why does it happen and how can I fix it?

EpicKip
  • 4,015
  • 1
  • 20
  • 37
Xnitor
  • 79
  • 1
  • 2
  • 12
  • 5
    Move `var times = new Times();` into the `for` loop – Dmitry Bychenko Mar 15 '19 at 11:58
  • 3
    `Times` is likely a class, which is a reference type, which means that every time you add it to the list, you're adding a reference to the object to the list, but you only have 1 object. So when you change that object, you change your single object. You don't have 8 copies of the object in the list, you have 8 references to the 1 object. Move the construction of the object into the for-loop. – Lasse V. Karlsen Mar 15 '19 at 11:58
  • Why are you using the name "i" for the index? Why not call it index? using the letter i makes it hard to read and can sometimes be confused with l or 1 – Hogan Mar 15 '19 at 11:59
  • @Hogan At this point, using `i` in a for loop as a name of index is canon. – aloisdg Mar 15 '19 at 12:01
  • @aloisdg -- that is my point -- it is not canon because it is moronic --- we should stop teaching it to new programmers it is fundamentally bad programming. – Hogan Mar 15 '19 at 12:05

2 Answers2

6

Its because its the same Times object every time, you have to make a new one in the loop:

for (int i = 0; i < 8; i++)
{
    var times = new Times();
    times.StartTime = startTime;
    times.EndTime = endTime;
    listOfTimes.Add(times);
    startTime++;
    endTime++;
}
EpicKip
  • 4,015
  • 1
  • 20
  • 37
0

EpicKip's answer already fix your problem (and I upvote it), but here is an alternative using Linq. If you are not familiar with Linq, check it ;)

public static List<Time> CreateListOfTimes()
{   
    return Enumerable.Range(8, 8).Select(i => new Times
    {
        StartTime = i,
        EndTime = i + 1
    }).ToList();
}

Here we use Enumerable.Range and Enumerable.Select. The ToList() is not really needed. I use it to respect the signature of CreateListOftimes().

aloisdg
  • 22,270
  • 6
  • 85
  • 105