1

ボクシングとアンボクシングを勉強していました。

私はこの例を経験しましたが、答えを理解できません。

誰か説明してくれませんか。

簡単な例を見ると、ボックス化とボックス化解除が何をするかはわかりますが、この例では少し混乱します。

ボックス化してからボックス化解除する例、トリッキーな例。

[struct|class] Point {
    public int x, y;    
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}    
Point p = new Point(1, 1);
object o = p; p.x = 2;
Console.WriteLine(((Point)o).x);

私は答えを次のように読みました:

場合によります!Point が構造体の場合、出力は 1 ですが、Point がクラスの場合、出力は 2 です! ボックス化変換では、ボックス化された値のコピーが作成され、動作の違いが説明されます。

これは((point)o).xボクシングまたはアンボクシングですか?

理解できませんでした、誰か私に説明してください。

答えが 1 であることはわかっていますが、class の場合はどうすれば 2 でしょうか?

4

5 に答える 5

4

誰もがエッセイを書いている理由はわかりませんが、説明するのは非常に簡単です。

  • を にキャストするstructobject、新しい にコピーさobjectれます。

  • を にキャストするobjectstruct、新しい にコピーさstructれます。

  • classesの間でキャストすると、オブジェクトの内容はコピーされません参照のみがコピーされます。

それが役立つことを願っています。

于 2013-08-05T03:04:37.773 に答える
1

C# は、構造体型が から派生したものであるかのように見せかけようとしますがObject、それは半分しか当てはまりません。CLI 仕様によると、構造体型仕様は実際には 2 種類のものを定義します: から派生するヒープ オブジェクトの型System.ValueType(そしてSystem.Object)、および格納場所の種類 (ローカル変数、静的変数、クラス フィールド、構造体フィールド、パラメータ、または配列スロット) から派生したものではありませんが、ヒープ オブジェクト型に暗黙的に変換可能です。

すべてのヒープ オブジェクト インスタンスには、型またはその親クラス (存在する場合) によって定義されたすべてのフィールドと、その型を識別するヘッダー、およびインスタンスに関するその他の情報が含まれています。すべての構造体型の格納場所には、その値を保持するために必要なバイト (プリミティブ型の場合) が含まれるか、すべてのフィールドの連結された値が保持されます。どちらの場合も、そのタイプを識別するヘッダーは含まれていません。代わりに、値の型は、生成されたコード内の情報に依存して、それらが何であるかを認識します。

値の型をその値の型の格納場所に格納すると、コンパイラは、元の値の型から取得した値で、格納先が占めるすべてのバイトを上書きします。ただし、値の型を参照型の格納場所 ( などObject) に格納しようとすると、ランタイムは値の型のすべてのデータを保持するのに十分なスペースを持つ新しいヒープ オブジェクトを、その型を識別するヘッダーと共に生成します。 、その新しいオブジェクトへの参照を宛先の場所に保存します。参照型を値型に型キャストしようとすると、ランタイムはまずオブジェクトが適切な型であることを確認し、適切な型である場合はデータをヒープ オブジェクトから宛先にコピーします。

インターフェイスとジェネリックが関係するいくつかのトリッキーなシナリオがあります。インターフェイス型は参照型ですが、構造体がインターフェイスを実装する場合、実装するメソッドは、ボックス化された構造体インスタンスをボックス化解除して再ボックス化しなくても、ボックス化された構造体インスタンスに直接作用する可能性があります。さらに、一般的な制約として使用されるインターフェイス タイプは、ボックス化を必要としません。List<int>.Enumeratorfunction のような値型の変数を渡すとEnumerateThings<TEnumerator>(ref TEnumerator it) where TEnumerator: IEnumerator<int>、そのメソッドはボックス化せずにその変数への参照を受け入れることができます。

于 2013-08-05T02:57:45.797 に答える
0

ポイントは構造体であり、構造体は値型であるため、渡されるときにコピーされます。

したがって、コピーを変更すると、オリジナルではなく、そのコピーのみが変更されます。

ただし、Point がクラスの場合は、参照によって渡されました。

したがって、コピーを変更すると、そのコピーとオリジナルだけが変更されます。

あなたの混乱について

object o = p; is boxing

一方

(Point)o is unboxing
于 2013-08-05T01:47:56.163 に答える
0

ボクシングを理解するには、値型と参照型の違いを理解する必要があります。

それを理解する最も簡単な方法は次のとおりだと思います。

「値型はインラインで割り当てられます。参照型は常にヒープに割り当てられます」

つまり、値の型 (struct、int、float、bool) をクラス変数 (パブリックまたはプライベート) として参照型の内部に追加すると、その参照型がヒープ上に存在するすべての場所にその値の型のデータが埋め込まれます。 .

関数内で値型を作成するが、それをパブリック/プライベート変数に割り当てない場合、その値型は関数スタックに割り当てられます (つまり、その関数を離れると収集されます)。

したがって、その背景知識を考えると、値の型を「ボックス化」するとどうなるかは一目瞭然です。その値の型 (インラインで割り当てられた場所) を取得し、それを参照型に変換する必要があります。 (ヒープ上に新しいオブジェクトを作成します)。

于 2013-08-05T02:01:56.807 に答える