C# 取消绑定到对象后更改结构字段

C# 取消绑定到对象后更改结构字段,c#,struct,boxing,unboxing,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() { S

我想知道是否有可能做到这一点,而不使用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)装箱是一种复制操作。你不是在修改盒装结构的值,你只是在修改一个副本,然后马上扔掉

这与二传手无关。您只是修改了错误的值:)

如果需要修改装箱结构,基本上需要手动复制,然后再次复制:

var p2 = (Point)o;
p2.y = 9;
o = (object)p2;
不用说,这有点浪费。如果您确实需要这样做(很难理解为什么),您可能需要创建一个手动装箱对象,例如

class MyBox<T> where T : struct
{
  public T Value;
}
类MyBox,其中T:struct
{
公共价值观;
}
这让你可以

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

请注意,
Value
是一个字段而不是属性-我们不是复制,而是直接引用“装箱”值。

如果您可以更改结构点,您可以做的是使该点实现一个接口,然后将装箱结构强制转换到接口。这是因为在将装箱点强制转换到接口时不会发生取消装箱

这是示例代码

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

好的,我知道+-它做什么,它将字段传递到堆栈的顶部,然后传递到堆,然后o有一个对堆的那部分的引用(仍在学习不恨xD),但我不能做o.y=9;那么我可以在装箱后更改此值吗?@NoobCoder否,装箱的值实际上是不可变的。您需要将新值框起来,并用新值替换旧引用
MyBox
对于该场景更有用,因为它避免了自动装箱-强制转换不会创建副本(当然,除非有一些自定义强制转换操作符:)。