装箱与拆箱

发布于 2024-07-17 02:57:17 字数 799 浏览 10 评论 0原文

我最近遇到的另一个 C# 面试问题是我是否知道装箱和拆箱是什么。 我解释过,值类型位于堆栈上,引用类型位于堆上。 当一个值被转换为引用类型时,我们称之为装箱,反之亦然。

然后他让我算一下:

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,确实如此。 但这根本不是装箱/拆箱的示例,这是正确的吗? 那么你会如何总结这一点呢?

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

Another recent C# interview question I had was if I knew what Boxing and Unboxing is.
I explained that value types are on Stack and reference types on Heap.
When a value is cast to a reference type, we call it boxing and vice versa.

Then he asked me to calculate this:

int i = 20;
object j = i;
j = 50;

What is i?

I messed it up and said 50, where its actually 20. Now I think understand it why, however when I was playing with different combinations I was surprised to see this:

Object a = 1; // Boxing
Object b = a; // referencing the pointer on stack to both objects on heap
a = 2; // Boxing

I was expecting to see b == 2 as well, but it isn't, why? Is it because the second boxing destroys and replaces the whole a object on the heap?

Because if I do this, it's fine:

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;

What is t2.x? It should be 3, and it is. But this is not an example of boxing / unboxing at all, is this correct? So how would you summarize this?

Could the values ever become the same in a boxing/unboxing conversion as above?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

2024-07-24 02:57:17

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

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

Very short: boxing means creating a new instance of a reference type. If you know this, you understand that one instance does not change by creating another.

What you are doing with a = 2 is not changing the value in the 'box', you are creating a new instance of a reference type. So why should anything else change?

厌味 2024-07-24 02:57:17
  1. 你是对的,第二个作业取代了第一个作业。 它不会更改装箱值。

  2. 您的示例没有使用拳击。 值 (int) 存储为 int 且未装箱。

  3. 不,拳击仍然保持不变性保证。

  1. You're right the second assignment replaces the first. It doesn't change the boxed value.

  2. Your example doesn't make use of boxing. The value (int) is stored as an int and not boxed.

  3. No, boxing still keeps the immutability guarantee.

红衣飘飘貌似仙 2024-07-24 02:57:17

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

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

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

即使像 Point 这样的可变结构在装箱时也无法更改。 要访问结构体的属性,您必须将其拆箱,这样您就无法就地更改装箱的结构体。

I was expecting to see b == 2 as well,
but it isn't, why? is it because the
second boxing destroys and replaces
the whole (a)-object on heap?

No, not exactly. It leaves the object as it is on the heap (as the b variable is also referencing it) and creates a new object for the new value, which the a variable will reference.

You are right that your second example does not use boxing. You can't access a value that is boxed in any other way than unboxing it, so there is no way to change a boxed value.

Not even a mutable struct like Point can be changed when boxed. To access the properties of the struct you have to unbox it, so you can't change the boxed struct in place.

拥有 2024-07-24 02:57:17

这是支持 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

Here's another interesting variation that supports Stefan's comments:

        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
忘年祭陌 2024-07-24 02:57:17

b 仍然是 1,因为 b 是仍然指向堆上值为 1 的对象的引用。a 是 2,因为您将它分配给堆上值为 2 的新对象。t2.x

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

b is still 1 because b is a reference that still points to the object on the heap with a value of 1. a is 2 because you assigned it to a new object on the heap with a value of 2.

t2.x is 3 because t and t2 are two different references to the same object on the heap.

蒗幽 2024-07-24 02:57:17

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

我认为您正在尝试执行以下操作:

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) 对象?

I think the answer to your question with unboxing is that: The result of an unboxing conversion is a temporary variable (more details: link).

I think you were trying to do sth like:

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

The above code won't compile - details in the link above, and I think this is the answer to your question:

I was expecting to see b == 2 as well,
but it isn't, why? is it because the
second boxing destroys and replaces
the whole (a)-object on heap?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文