2

I have an unknown array of struct type. When I'm trying to get some index I get a NEW instance of this object:

var inst = ((SomeStruct)((Array)arrOfSomeStruct).GetValue(0));

Now inst is a different instance from arrOfSomeStruct[0] .

What is the best or the fastest way to get the original instance of the array item, and NOT by using [ ] operators?

3
  • What are you trying to do that requires the source struct? Commented Aug 9, 2016 at 6:57
  • What are you really trying to achieve? As soon as you assign a struct value to a variable, as in var inst2 = inst1;, the value is copied, so a new instance is created. As soon as you unbox a struct value that has been residing in an object box, as in var inst = (SomeStruct)obj;, a new value/instance is created. As soon as you implicitly box a struct value, as in public object GetValue() { /* ... */ return someStruct /* boxing! */; }, a new instance is created in a new box. Is your struct mutable or immutable since you care about all this? Commented Aug 9, 2016 at 11:56
  • var inst = orig_arr.GetValue(0); inst.x = 5; // Now orig_arr.x != inst.x Commented Aug 10, 2016 at 11:12

2 Answers 2

4

You can't get the original if it is a value type. Every Value Type will be copied if it is returned from the method or passed into the method.

To work as you want you must use a reference type(class)

Sign up to request clarification or add additional context in comments.

Comments

2

This is default behavior of interaction with a struct. It is copied, not referenced. This is the same for every exchange with a struct, not just your GetValue method (also this[index] for example).

As Jeppe Stig Nielsen commented:

... for an array of value types, .GetValue(0) returns a reference to a boxed copy of the struct value. On the other hand [0] is the original struct value. If you assign to a variable, then a copy is made, as in var valueCopy = arr[0];. However, that is mostly relevant for mutable value types. If the struct has a member that mutates the struct value, then arr[0].MutateValue(); will mutate the original. Of course valueCopy.MutateValue(); will change the copy.

The best option you have is to make the struct an object, ie. move to a class.

In some extreme cases, the use of unsafe code is a last resort:

unsafe
{
    Point p = new Point(1, 2);
    Point*[] points = new Point*[] { &p };

    Point* p2 = points[0];

    p2->X = 2; // this changes both p and p2
}

1 Comment

To clarify, for an array of value types, .GetValue(0) returns a reference to a boxed copy of the struct value. On the other hand [0] is the original struct value. If you assign to a variable, then a copy is made, as in var valueCopy = arr[0];. However, that is mostly relevant for mutable value types. If the struct has a member that mutates the struct value, then arr[0].MutateValue(); will mutate the original. Of course valueCopy.MutateValue(); will change the copy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.