为什么我无法修改拆箱转换的结果?

2024-04-15

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 允许的地方。

对于那些不知道的人来说,unbox is not http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.unbox.aspx需要创建一个副本值类型 https://msdn.microsoft.com/en-us/library/t63sy5hs.aspx,而是将指向该值的指针推入堆栈。 只有赋值才会创建副本。


由于值类型的工作方式,盒装Point是原件的副本,并通过投射回“拆箱”它Point创建另一个副本。来自 C# 语言规范(第 1.3 节,“类型和变量”):

当值类型的值转换为对象类型时,会分配一个对象实例(也称为“盒子”)来保存该值,并将该值复制到该盒子中。相反,当对象引用转换为值类型时,会检查所引用的对象是否是正确值类型的框,如果检查成功,则复制框中的值。

修改副本无论如何都不会改变原始版本,因此允许它没有多大意义。

至于C++……嗯……当然,C#的规则不一定适用于它。 :) 实际上,CLR 在指针和引用方面的灵活性比您最初想象的要高得多,而以这种灵活性而闻名的 C++ 可能会利用它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我无法修改拆箱转换的结果? 的相关文章

随机推荐