Reputation: 229
I have a simple class which has boolean field:
public struct Foo { bool isAvailable; }
Now I have a List of foos:
List < Foo > list = new List< Foo >();
Later on I enumerate each foo in the list and try to update its isAvailable field:
foreach(Foo foo in list) {
foo.isAvailable = true;
}
But the above code never updates the list. What am I doing wrong here and what's its remedy.
Upvotes: 3
Views: 437
Reputation: 11
When you fill list, you need to create new istance for each Foo Class.
List list = new List(); Foo foo = new Foo();
foo.isAvailable = false; list.Add(foo);
foo = new Foo(); list.Add(foo);
foo = new Foo(); list.Add(foo);
if you fill on this way:
List list = new List(); Foo foo = new Foo(); list.Add(foo); list.Add(foo); list.Add(foo);
you are reference on same memory location on stack for each object.
Upvotes: 0
Reputation: 1504062
It's because Foo
is a mutable struct.
When you fetch the value from the list, it's making a copy - because that's how value types behave. You're changing the copy, leaving the original value unchanged.
Suggestions:
While you could change your code to iterate over the list in a different way and replace the value each time, it's generally a bad idea to do so. Just use a class... or project your list to a new list with the appropriate values.
Original answer, when Foo was a class
It should work fine. For example, here's a short but complete program which does work:
using System.Collections.Generic;
public class Foo
{
public bool IsAvailable { get; set; }
public string Name { get; set; }
public override string ToString()
{
return Name + ": " + IsAvailable;
}
}
class Test
{
static void Main()
{
List<Foo> list = new List<Foo>()
{
new Foo { Name = "First", IsAvailable = true },
new Foo { Name = "Second", IsAvailable = false },
new Foo { Name = "Third", IsAvailable = false },
};
Console.WriteLine("Before:");
list.ForEach(Console.WriteLine);
Console.WriteLine();
foreach (Foo foo in list)
{
foo.IsAvailable = true;
}
Console.WriteLine("After:");
list.ForEach(Console.WriteLine);
}
}
Try to adapt your current code to a similar short but complete program which doesn't work, post that, and we can work out what's going on.
Upvotes: 7
Reputation: 60276
You're using a struct as Foo
, not a class. Structs are copied, not referenced, and therefore you only modify the copy and not the object stored in the list.
So you basically have two options:
Make it a class
Re-assign the result to the list. To do so, I'd iterate using an index instead of using foreach
.
Upvotes: 2