c# - 为什么我不能修改拆箱转换的结果?

标签 c# il boxing unboxing

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 ,unboxnot需要创建 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/

相关文章:

java - 与 Java 不同,为什么装箱是 .NET 未缓存的原始值类型?

java - (在 Java 中拆箱原始数组

c# - 如何避免不可能的枚举值?

c# - cecil : Instruction. Instruction.OpCode.Code值对应的操作数类型

c# - 为 .Net 平台生成 IL

f# - F# 函数的通用版本导致无效的 IL?

iphone - 有没有一种从数组中获取 float 的简写方法?

c# - 在 WCF 服务中获取请求者信息

c# - 持久 Entity Framework 查询缓存

c# - WPF 绑定(bind)源