拆箱后将结构字段更改为对象

时间:2015-10-06 11:44:14

标签: c# struct boxing unboxing

我想知道是否可以这样做,而不使用setter。

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);
    }
}

是否可以通过强制转换和取消装箱来更改y值? 提前谢谢

2 个答案:

答案 0 :(得分:2)

(Un)boxing 是一个复制操作。您没有修改盒装结构的价值,而只是简单地修改了一个副本 - 您之后就会丢弃它。

这与setter无关。您只需修改错误的值:)

如果您需要修改盒装结构,则需要手动复制它,然后再将其复制回来:

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

毋庸置疑,这有点浪费。如果你真的需要做这样的事情(并且很难看到为什么),你可能想要创建一个手动拳击对象 - 比如

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

允许你这样做

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

请注意,Value字段而非属性 - 我们不是直接引用&#34;盒装&#34;值。

答案 1 :(得分:0)

如果你可以改变struct Point,你可以做的是使Point实现一个接口,然后将盒装结构转换为接口。这是有效的,因为当您将盒装点转换为界面时不会发生拆箱。

以下是示例代码

    public static void Main()
    {
        Point p = new Point();
        p.x = 7;
        object o = p;
        ((IModifiablePoint)o).Y = 9;   //  This works
        ((Point)o).Print();

    }

    interface IModifiablePoint
    {
        int X { get; set; }
        int Y { get; set; }
    }

    struct Point : IModifiablePoint
    {
        public int x, y;

        public int X
        {
            get { return x; }

            set { x = value; }
        }

        public int Y
        {
            get { return y; }

            set { y = value; }
        }

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