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
}
struct?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 anobjectbox, as invar inst = (SomeStruct)obj;, a new value/instance is created. As soon as you implicitly box a struct value, as inpublic 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?var inst = orig_arr.GetValue(0); inst.x = 5; // Now orig_arr.x != inst.x