2

I am having a problem were the reference to an object in a list is lost, this is how I elaborated my code :

PropertyObject[] myProperties = new PropertyObject[200];
var objParent = new Parent();
var objProperty = new PropertyObject();

myProperties[0] = objProperty;
objParent.property = myProperties[0];

Now when I modify objParent.property it does not modify the object in the myProperties array, any workaround? I need this so that I don't have to iterate over the array.

This is how I modify the object :

public void modifyObject(ref Parent objectToModify) {
   objectToModify.property.isThisCrazy = true;
}

Then I just invoke the modifyObject method.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325

2 Answers2

4

structs are meant to be immutable. Assinging a struct to another variable will cause the struct to be copied.

When assigning properties on the one instance, the properties of the other other instance of the struct aren't changed. Hence, you don't see updated in the other reference.

Sample code demonstrating the problem with structs:

struct X
{
    public string Y { get; set; }

    public X(string y) : this()
    {
        Y = y;
    }
}

X x = new X("abc");
X x2 = x;

x2.Y = "def";

Console.WriteLine(x.Y);
Console.WriteLine(x2.Y);

With classes you'd expected x.Y and x2.Y to be the same, but not with structs.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • 3
    Structs are not inherently immutable. Their copy semantics make mutable structs difficult to work with. Therefore it is advisable that they are immutable but it is very possible to have mutable structs. – Mike Zboray Apr 01 '15 at 07:58
  • @mikez: Agreed. Updated the first sentence a little. – Patrick Hofman Apr 01 '15 at 07:59
  • You: *in fact you are creating new instances on setting a property / field.* No. The new instance is created when you assign the struct to another variable (or pass it as value parameter to a method, or box it). In your example, the line `X x2 = x;` creates a new instance. Setting the value of the property `Y` does not create a new instance of the struct! – Jeppe Stig Nielsen Apr 01 '15 at 08:26
2

You write that a "reference to an object" is lost, but a struct has no "reference" to it.

A struct has value-type semantics. So when you assign with =, a copy of the right-hand side is made. You do:

myProperties[0] = objProperty;

This copies the value, and puts a copy inside the 0th entry of the array.

If you later modify the "original" instance objProperty, that change will not be present in the copy held in the array.

This is not really an array issue. The same happens with all struct value assignments. For example:

var objProperty2 = objProperty;

If the original objProperty is mutated afterwards, the copied value objProperty2 will be unaffected. See for example C# Reference type assignment VS value type assignment.

Some people consider mutable structs evil.

Community
  • 1
  • 1
Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181