C# 取消绑定到对象后更改结构字段
我想知道是否有可能做到这一点,而不使用setterC# 取消绑定到对象后更改结构字段,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
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
对于该场景更有用,因为它避免了自动装箱-强制转换不会创建副本(当然,除非有一些自定义强制转换操作符:)。