質問

最近の C# 面接でのもう 1 つの質問は、ボクシングとアンボクシングとは何かを知っているかどうかというものでした。値型はスタック上にあり、参照型はヒープ上にあると説明しました。値が参照型にキャストされることをボックス化と呼び、その逆のことも同様です。

それから彼は私にこれを計算するように言いました。

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 それもそうですが、そうではないのはなぜでしょうか?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 であるはずですが、その通りです。しかし、これはボックス化/ボックス化解除の例ではまったくありません。これは正しいでしょうか?では、これをどのように要約しますか?

上記のボックス化/アンボックス化変換で値が同じになる可能性はありますか?

役に立ちましたか?

解決

  1. おっしゃるとおり、2 番目の割り当てが最初の割り当てに置き換わります。ボックス内の値は変更されません。

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

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

他のヒント

とても短い:ボクシングの手段 参照型の新しいインスタンスを作成する. 。これを知っていれば、あるインスタンスが別のインスタンスを作成しても変更されないことがわかります。

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

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

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

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

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

ステファンのコメントを裏付ける別の興味深いバリエーションを次に示します。

        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

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

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

開梱に関する質問に対する答えは次のとおりだと思います。アンボックス化変換の結果は一時変数です (詳細: リンク).

次のような 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)オブジェクト全体を破壊し、置き換えるからでしょうか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top