Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 装箱与拆箱_C#_Boxing_Unboxing - Fatal编程技术网

C# 装箱与拆箱

C# 装箱与拆箱,c#,boxing,unboxing,C#,Boxing,Unboxing,最近我在采访中遇到的另一个问题是,我是否知道什么是装箱和拆箱。 我解释了值类型在堆栈上,引用类型在堆上。 当一个值被转换为引用类型时,我们称之为装箱,反之亦然 然后他让我计算一下: int i = 20; object j = i; j = 50; 什么是i 我搞砸了,说是50,实际上是20。现在我想我明白了为什么,但是当我玩不同的组合时,我惊讶地发现: Object a = 1; // Boxing Object b = a; // referencing the pointer on st

最近我在采访中遇到的另一个问题是,我是否知道什么是装箱和拆箱。 我解释了值类型在堆栈上,引用类型在堆上。 当一个值被转换为引用类型时,我们称之为装箱,反之亦然

然后他让我计算一下:

int i = 20;
object j = i;
j = 50;
什么是
i

我搞砸了,说是50,实际上是20。现在我想我明白了为什么,但是当我玩不同的组合时,我惊讶地发现:

Object a = 1; // Boxing
Object b = a; // referencing the pointer on stack to both objects on heap
a = 2; // Boxing
我本来也希望看到
b==2
,但事实并非如此,为什么?这是因为第二个装箱销毁并替换堆上的整个
a
对象吗

因为如果我这样做,那很好:

public class TT
{
    public int x;
}

TT t = new TT();
t.x = 1;
TT t2 = new TT();
t2.x = 2;
t = t2;
t.x = 3;
什么是
t2.x
?应该是3,现在是。但这根本不是装箱/拆箱的例子,对吗?那么你如何总结这一点呢

装箱/拆箱转换中的值是否会与上述值相同?

  • 你说得对,第二个任务取代了第一个任务。它不会更改装箱的值

  • 你的例子没有使用拳击。值(int)存储为int,不装箱

  • 不,装箱仍然保持不变性保证

  • 我也希望看到b==2, 但事实并非如此,为什么?是因为 第二节拳击摧毁并取代 堆上的整个(a)-对象

    不,不完全是。它使对象保持在堆上的状态(因为
    b
    变量也在引用它),并为新值创建一个新对象,而
    a
    变量将引用该对象

    您的第二个示例没有使用拳击是对的。除了解除装箱,您无法访问以任何其他方式装箱的值,因此无法更改装箱的值


    装箱时,即使是像
    Point
    这样的可变结构也无法更改。要访问结构的属性,您必须取消装箱,因此无法就地更改装箱结构。

    b仍然是1,因为b是仍然指向堆上值为1的对象的引用。a是2,因为您将其分配给堆上的一个值为2的新对象


    t2.x是3,因为t和t2是对堆上同一对象的两个不同引用。

    我认为对您的问题的解装箱的答案是:解装箱转换的结果是一个临时变量(更多详细信息:)

    我想你想做的是:

    object a = new Point(10,10);
    object b = new Point(20,20);
    a = b;
    
    ((Point) b).X = 30; //after this operation also a.X should be 30
    
    上面的代码无法编译-详细信息请参见上面的链接,我想这就是您问题的答案:

    我也希望看到b==2, 但事实并非如此,为什么?是因为 第二节拳击摧毁并取代 堆上的整个(a)-对象


    非常简短:装箱意味着创建引用类型的新实例。如果您知道这一点,您就知道创建另一个实例不会改变一个实例


    使用
    a=2
    所做的不是更改“框”中的值,而是创建引用类型的新实例。那么,为什么还要做其他的改变呢?

    这里有另一个支持Stefan评论的有趣变化:

            int i = 2;
            object a = i; // Boxing
            object b = a; // Referencing same address on heap as 'a', b == a
    
            b = i; // New boxing on heap with reference new address, b != a
    

    嗨,谢谢你的回答。请您详细说明一下“拳击仍然保持不变性保证”?感谢kaveMost值类型是不可变的,例如:一个int只能有一个值。如果你改变了值,你实际上是在创建一个新的整型。NET对装箱对象保持这种不变性:如果你给它赋值,你就是在创建一个新的装箱整型。这同样适用于装箱结构。这是完全有意义的。Thanks@grover:什么是不变性保证?任何装箱的值类型都可以通过用C++/CLI编写的可信且可验证的代码轻松地进行自由变异。值类型,如
    List.Enumerator
    ,它实现了可变接口,当装箱时,将表现为可变类类型。很好的解释,现在当您取消装箱时会发生什么?引用类型的新实例是否被销毁?引用类型总是被垃圾收集销毁。因此,当不再引用时,它将被销毁。简短n甜美的回答,非常好。值得注意的是,在C++/CLI中,直接在可信和可验证的代码中修改盒装堆对象没有困难。另请参阅,以获取一般性阅读