Search code examples
c#structboxingunboxing

Changing struct fields after unboxing to object


I was wondering if it was possible to do this, without using setters.

void Main()
{
    Point p = new Point();
    p.x = 7;
    Object o = p;
    ((Point)o).y = 9;   //  This doesnt work !
    ((Point)o).Print();

}

struct Point 
{
    public int x, y;
    public void Print() 
    {
        System.Console.WriteLine("x= "+this.x+"\ny= "+this.y);
    }
}

Is it possible to change the y value, just by casting, and unboxing? thanks in advance


Solution

  • (Un)boxing is a copy operation. You're not modifying the value of your boxed structure, you're simply modifying a copy - which you throw away right after.

    This has nothing to do with setters. You're simply modifying the wrong value :)

    If you need to modify a boxed struct, you need to basically copy it manually, and then copy it back again:

    var p2 = (Point)o;
    p2.y = 9;
    o = (object)p2;
    

    Needless to say, this is a bit wasteful. If you really need to do something like this (and it's hard to see why), you might want to create a manual boxing object instead - something like

    class MyBox<T> where T : struct
    {
      public T Value;
    }
    

    Which allows you to do

    var o = (object)new MyBox<Point> { Value = p };
    ((MyBox<Point>)o).Value.y = 9;
    

    Note that Value is a field not a property - instead of copying, we're directly referencing the "boxed" value.