I have a List of structure.In the loop i am trying to modify the object's property,which is happening,but when i (Quick look in Visual studio)look into the list object ,the new value is not reflecting.Is it by virtue that the structure's object cannot be modified when in a collection? I am using generics list with the struct as the type in the list
If you are using a foreach loop you probably got
Error Message Cannot modify members of 'variable' because it is a 'read-only variable type'
This error occurs when you try to modify members of a variable which is read-only because it is in a special construct.
One common area that this occurs is within foreach loops. It is a compile-time error to modify the value of the collection elements. Therefore, you cannot make any modifications to elements that are value types, including structs.
You could however try
struct MyStruct
{
public int i;
}
List<MyStruct> list = new List<MyStruct>
{ new MyStruct { i = 1 }, new MyStruct { i = 2 } };
for(int i = 0; i < list.Count; i++)
{
MyStruct val = list[i];
val.i++;
list[i] = val;
}
EDIT
See also Structs Tutorial
Structs vs. Classes
Structs may seem similar to classes, but there are important differences that you should be aware of. First of all, classes are reference types and structs are value types.
I THINK i know what the problem might be.
struct Astruct
{
int amember;
}
List < Astruct > listofStructs;
foreach(Astruct A in listofStructs)
{
A.amember = 1337;
}
if this is what you are doing...
when you use structs in c# they are not referenced but copied! so that means the contents of your list is being COPIED to A, so when you change A it doesn't change the value in the list!
to solve this problem (if this is your problem...) either use CLASSES rather than STRUCTS, that way A would be a reference, OR use a manual iterating for loop instead, ie:
for(int i=0;i < listofStructs.Count;i++)
{
listofStructs[i].amember = 1337;
}
alternatively, if you’re using a list, you maybe should use an iterator or something... but the above should definitely fix that problem.
Given the information in your post (although I'd have liked to see the code itself), let me put forth the most probable issue and its fix.
foreach(var s in listOfStructs)
{
s.Property = x;
}
s is assigned to a copy of the actual struct in the collection. s.set_Property is now modifying the copy which is thrown away at the end of the current iteration.
This is because 2 value type variables cannot point to the same instance.
struct1 = new MyStruct(100, 200);
struct2 = struct1; // struct2 is now a copy of struct1
Now to the problem of how do you modify the instances in a collection:
Get the object to modify in a local variable (copy created). Modify it. Now remove the original object and insert the copy. use listOfStructs[i] = modifiedInstance
.
You mention "modify the object's property" in the context of a struct, but importantly a struct is not an object. Other people have answered as to the issue with structs being copied (and changes discarded), but to take that further the real problem here is that you have a mutable (changeable) struct at all. Unless you are on XNA (or similar) there is simply no need.
If you want to be able to change properties, make it a class:
public class Foo {
public string Bar {get;set;}
}
This is now a reference-type, and your changes (obj.Bar = "abc";
) will be preserved through the foreach. If you really want/need a struct, make it immutable:
public struct Foo {
private readonly string bar;
public string Bar { get {return bar; }}
public Foo(string bar) {this.bar = bar;}
}
Now you can't make the mistake of changing the value of a copy; you would instead have to use the indexer to swap the value (list[i] = new Foo("abc");
). More verbose (and you can't use foreach
), but correct.
But IMO, use a class. Structs are pretty rare, to be honest. If you aren't sure: class.