6

私はこの段落を理解しようとしてきましたが、どういうわけか私はそれを頭の中で仮想化できませんでした。誰かがそれを少し詳しく説明してください:

開箱はボクシングの正反対ではありません。開梱作業は、ボクシングよりもはるかに低コストです。ボックス化解除は、実際には、オブジェクト内に含まれる生の値型(データフィールド)へのポインターを取得する操作にすぎません。事実上、ポインタはボックス化されたインスタンスのボックス化されていない部分を参照します。したがって、ボクシングとは異なり、ボクシングの解除にはメモリ内のバイトのコピーは含まれません。この重要な説明を行った後、開開操作の後には通常、フィールドをコピーすることに注意することが重要です。

リヒター、ジェフリー(2010-02-05)。C#経由のCLR(Kindleの場所4167-4171)。OReillyMedia-A.Kindle版。

4

1 に答える 1

6

intをボックス化するには、構造体が保持するすべてのデータを保持するのに十分な大きさのオブジェクトをヒープ上に作成する必要があります。ヒープに新しいオブジェクトを割り当てるということは、GCがスポットを見つけるために作業し、GCがその存続期間中および存続後にオブジェクトをクリーンアップ/移動するために作業することを意味します。これらの操作は、それほど高価ではありませんが、安くはありません。

値型のボックスを解除するには、いわばポインタの参照を解除するだけです。object実際の値の場所を見つけるには、参照(あなたが持っているもの)を見る必要があります。メモリ内の値を検索するのは非常に安価です。そのため、その段落では「開梱」が安価であると述べています。

アップデート:

ボックス化されていない値型は通常、ボックス化されていない直後に他の場所にコピーされますが、常にそうであるとは限りません。次の例を考えてみましょう。

public struct MyStruct
{
  private int value = 42;
  public void Foo()
  {
    Console.WriteLine(value);
  }
}

static void Main()
{
  object obj = new MyStruct();
  ((MyStruct)obj).Foo();
}

MyStructはボックス化されていますobjが、ボックス化されていない場合、どこにもコピーされることはなく、メソッドが呼び出されるだけです。同様に、構造体からプロパティ/フィールドを引き出して、全体をコピーする必要なしに、その一部だけをコピーすることができます。これは少し不自然に見えるかもしれませんが、それでも完全にばかげているわけではありません。とは言うものの、引用が示すように、箱を開けた後でも構造体をコピーする可能性があります。

于 2012-04-14T02:15:13.110 に答える