Click here to Skip to main content
15,903,012 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I would like to do the following:
C#
public struct MyDefinition
{
  public Int32 ID;
  public string remember;
  public Color color;
  public MyDefinition(Int32 ID, string remember, Color color)
  {
    this.ID = ID;
    this.remember = remember;
    this.color = color;
  }
}

//and here is my List of structs:
private List<MyDefinition> things = new List<MyDefinition>();

private void FillThings()
{
  things.Add(new MyDefinition(1,"",Color.Red))
  things.Add(new MyDefinition(2,"",Color.Blue))
}

public void Remember(string RememberThis)
{
  //What to do here to update things[2].remember?
}


I have tried to set the value
C#
things[2].remember = "rememberthis";

but it forgets the value.

I have also tried to implement a method in the struct
C#
public SetRemember(string remember)
{
  this.remember = remember;
}

this method indeed sets the remember value in the struct when I debug, but as soon as it leaves the method the remember string is forgotten. I read something about using Interface, but I cannot get that clear.

Any ideas?
Posted
Comments
johannesnestler 17-Oct-13 10:44am    
Griff's solution is very good - but in your case it seems there is no good reason to use a struct (this is .NET and not C++), so just use a class, and access/modify your objects properties as needed. For me a general rule of thumb is: There has to be a VERY good reason to create a value type, you have one?

Firstly, there is no element at index 2, since you did not add three values. There are elements at indexes 0 and 1, but not 2...

Secondly, that is exactly what I would expect: a struct and a class have an important difference: a struct is a value type, a class is a reference type.
You can't write:
C#
things[index].remember = "rememberthis";
because the system will complain:
"Cannot modify the return value of 'System.Collections.Generic.List<complexfilterdemo.frmtester.mydefinition>.this[int]' because it is not a variable"</complexfilterdemo.frmtester.mydefinition>
And that makes sense, because it is a copy of a value type! If you want to "remember" your change, then you need to do this:
C#
MyDefinition md = things[1];
md.remember = "hello";
things[1] = md;
Because when you get or set the value of a value type you are copying the type instance, not getting another reference to the same instance. For proof, try this:
C#
Console.WriteLine("'{0}'", things[1].remember);
MyDefinition md = things[1];
md.remember = "hello";
Console.WriteLine("'{0}':'{1}'", things[1].remember, md.remember);
things[1] = md;
Console.WriteLine("'{0}':'{1}'", things[1].remember, md.remember);
md.remember = "goodbye";
Console.WriteLine("'{0}':'{1}'", things[1].remember, md.remember);
You will get:
''
'':'hello'
'hello':'hello'
'hello':'goodbye'

Which only makes sense if the values are being copied, not referenced.
 
Share this answer
 
Comments
Mart Rijkers 17-Oct-13 7:17am    
Thanks, I indeed made a mistake on the number of elements, it is because I typed this example to not bother you with all overhead in my code:-)

Very good explanation
OriginalGriff 17-Oct-13 7:19am    
You're welcome!
Are you sure, that your List even has three elements? In the example you are only adding two.

Another problem could be that structs in C# are by definition value types. So it is possible that things[2].remember gets you a temporary copy of the object and sets the member in the copy. In this case you would have to do something like this:
C#
MyDefinition temp = things[2];
temp.remember = "rememberthis";
things[2] = temp;

Alternatively you could change the struct to a class. In this case the list would just store the references to the objects, so you could set the members like you originally intended.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900