28

私が最近受けたもう1つの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たが、そうではありません、なぜですか?a2番目のボクシングがヒープ上のオブジェクト全体を破壊して置き換えるためですか?

私がこれを行う場合、それは問題ないからです:

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でなければなりません。しかし、これはボクシング/アンボクシングの例ではありません、これは正しいですか?では、これをどのように要約しますか?

ボクシング/アンボクシングの変換で上記と同じ値になる可能性はありますか?

4

6 に答える 6

8

非常に短い:ボクシングとは、参照型の新しいインスタンスを作成することを意味します。これを知っていれば、あるインスタンスが別のインスタンスを作成しても変更されないことを理解できます。

「ボックス」の値を変更するのでa = 2はなく、参照型の新しいインスタンスを作成します。では、なぜ他に何かを変更する必要があるのでしょうか。

于 2009-04-18T22:55:43.797 に答える
5
  1. そうです、2番目の割り当てが最初の割り当てに置き換わります。ボックス化された値は変更されません。

  2. あなたの例はボクシングを利用していません。値(int)は、ボックス化されずにintとして格納されます。

  3. いいえ、ボクシングは依然として不変性の保証を維持します。

于 2009-04-18T21:12:45.197 に答える
2

私もb==2を見ることを期待していましたが、そうではありません、なぜですか?2番目のボクシングがヒープ上の(a)オブジェクト全体を破壊して置き換えるためですか?

いいえ、正確ではありません。オブジェクトをヒープ上にそのまま残し(b変数もオブジェクトを参照しているため)、変数が参照する新しい値の新しいオブジェクトを作成しaます。

2番目の例ではボクシングを使用していないのは正しいです。ボックス化された値には、ボックス化を解除する以外の方法でアクセスできないため、ボックス化された値を変更する方法はありません。

Pointボックス化された場合、のような変更可能な構造体でさえ変更することはできません。構造体のプロパティにアクセスするには、ボックスを解除する必要があるため、ボックス化された構造体をその場で変更することはできません。

于 2009-04-18T21:34:29.747 に答える
2

ステファンのコメントをサポートする別の興味深いバリエーションは次のとおりです。

        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
于 2012-07-12T18:24:38.003 に答える
1

bは、値1のヒープ上のオブジェクトを指す参照であるため、bは1のままです。値2のヒープ上の新しいオブジェクトに割り当てたため、aは2です。

tとt2は、ヒープ上の同じオブジェクトへの2つの異なる参照であるため、t2.xは3です。

于 2009-04-18T21:38:54.747 に答える
0

アンボックス化に関するあなたの質問への答えは次のとおりだと思います。アンボックス化変換の結果は一時変数です(詳細:link)。

私はあなたが次のようなsthをしようとしていたと思います:

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を見ることを期待していましたが、そうではありません、なぜですか?2番目のボクシングがヒープ上の(a)オブジェクト全体を破壊して置き換えるためですか?

于 2009-04-18T22:27:13.770 に答える