struct Point
{
public int x;
public int y;
}
void Main()
{
Point p;
p.x = 1;
p.y = 1;
Object o = p;
((Point) o).x = 4; // error
((Point) o).x = 5; // error
((Point) o).x = 6; // error
p = (Point) o // expect 6
}
为什么不编译成
ldloc.1 // o
unbox Point
ldc.i4.4
stfld Point.x
C++ CLI 允许的地方。
不知道的 friend ,unbox
是not需要创建 value types 的副本,而是将指向值的指针插入堆栈。
只有赋值会创建副本。
最佳答案
由于值类型的工作方式,装箱的 Point
是原始文件的副本,通过转换回 Point
来“拆箱”它会创建另一个副本。来自 C# 语言规范(§1.3,“类型和变量”):
When a value of a value type is converted to type object, an object instance, also called a “box,” is allocated to hold the value, and the value is copied into that box. Conversely, when an object reference is cast to a value type, a check is made that the referenced object is a box of the correct value type, and, if the check succeeds, the value in the box is copied out.
修改副本无论如何都不会改变原件,所以允许它没有多大意义。
至于C++……嗯……当然,C#的规则不一定适用于它。 :) CLR 实际上在指针和引用方面比您最初想象的要灵活得多,而以这种灵 active 着称的 C++ 可能会利用它。
关于c# - 为什么我不能修改拆箱转换的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17280547/