Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying a particular item in a list of structures

Tags:

c#

I have list of structure. I want to modify a particular data from the structure. And the structure is at the particular index location of the List.

I want to do something like this:

struct sample
{
  int a;
  string name;
}

List<sample> list = new List<sample>();


for(int i=0; i < list.Count; i++)
{
  list[i].a = someotherlist[i].data;
}
like image 631
Sourabh Avatar asked Feb 01 '26 07:02

Sourabh


2 Answers

The problem is that the list indexer creates a copy of the struct, i.e. it is really:

for(int i=0; i < list.Count; i++)
{
  var completelyIsolatedClone = list[i];
  completelyIsolatedClone.a = someotherlist[i].data;
}

The compiler is preventing you making an obvious mistake. The code you have uses the get, mutates a separate copy of the data, but never puts it back - so your change doesn't do anything useful. Note that the Mono folks think it would be nice if it worked your way, though: http://tirania.org/blog/archive/2012/Apr-11.html

Note that an array works differently; with an array you are touching the struct in place, so the following would work fine:

for(int i=0; i < list.Count; i++)
{
  someArray[i].a = someotherlist[i].data;
}

Another approach is to copy the data out (the get accessor), mutate it, and put it back:

for(int i=0; i < list.Count; i++)
{
  var completelyIsolatedClone = list[i];
  completelyIsolatedClone.a = someotherlist[i].data;
  list[i] = completelyIsolatedClone;
}

or better, acoid mutable structs completely, perhaps with a method that applies the change to a new copy:

for(int i=0; i < list.Count; i++)
{
  list[i] = list[i].SetA(someotherlist[i].data);
}

where SetA creates a new struct, like DateTime.AddDays etc, i.e.

public SomeType SetA(int a) {
    return new SomeType(this.X, this.Y, a, this.Z);
}
like image 71
Marc Gravell Avatar answered Feb 03 '26 19:02

Marc Gravell


The reason you can't do it is because Sample is a struct, if you change it to a class then you can modify it. Structures are passed by value, that is, when a structure is returned by a method, a copy of the structure is returned, not the orginal structure. So when list[i].a = someotherlist[i].data; is run, you are actually modifying the copy and the orginal structure is not being changed. The compilers prevents you from doing this as it is probably not what you had intended.

You may look at this thread Why couldnot I modify the value of item from Generic Collections) ?

like image 41
Habib Avatar answered Feb 03 '26 19:02

Habib