在拆箱到对象后更改结构字段

本文关键字:结构 字段 对象 | 更新日期: 2023-09-27 18:16:18

我想知道是否有可能做到这一点,而不使用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值?提前感谢

在拆箱到对象后更改结构字段

(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是一个字段而不是一个属性-而不是复制,我们直接引用"boxed"值

如果您可以更改结构体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);
        }
    }
}