1. ホーム
  2. c#

[解決済み] なぜC#ではボクシングとアンボクシングが必要なのか?

2022-03-15 22:34:15

質問

なぜC#では箱詰めと箱出しが必要なのですか?

ボクシングとアンボクシングは知っているが、その本当の使い方がわからない。なぜ、どこで使うべきなのでしょうか?

short s = 25;

object objshort = s;  //Boxing

short anothershort = (short)objshort;  //Unboxing

解決方法は?

<ブロッククオート

なぜ

統一された型システムを持ち、参照型がその基礎となるデータを表現する方法とは全く異なる表現を値型に持たせること(例えば、参照型がその基礎となるデータを表現する方法として int は32ビットのバケツに過ぎず、参照型とは全く異なるものです)。

こんな風に考えてみてください。あなたは、変数 o 型の object . そして今、あなたは int の中に入れて、それを o . o はどこかの何かを参照するものであり int は明らかにどこかの何かを参照していません(結局のところ、それは単なる数字なのです)。そこで、あなたはこうします。 object を格納することができます。 int で、そのオブジェクトへの参照を o . この処理をボクシングと呼んでいます。

つまり、統一された型システムを持つことにこだわらないのであれば(つまり、参照型と値型は非常に異なる表現を持っており、この2つを"represent"する共通の方法を必要としない)、ボクシングは必要ないのです。を持つことにこだわらないのであれば int は、その基礎となる値を表します(つまり、代わりに int も参照型であり、単にその基本的な値への参照を格納する)であれば、ボクシングは必要ありません。

どこで使えばいいのでしょうか。

例えば、旧コレクション型 ArrayList を食べるだけです。 object s. つまり、どこかに住んでいるsomethingへの参照だけを保存します。ボクシングがなければ int をこのようなコレクションに入れることができます。しかし、ボクシングを使えば、それが可能になる。

ジェネリックの時代には、このようなことは必要なく、一般的には何も考えなくてよいのです。しかし、注意しなければならない点がいくつかあります。

これは正しい。

double e = 2.718281828459045;
int ee = (int)e;

これは違います。

double e = 2.718281828459045;
object o = e; // box
int ee = (int)o; // runtime exception

その代わり、こうしなければなりません。

double e = 2.718281828459045;
object o = e; // box
int ee = (int)(double)o;

まず、明示的にアンボックスする必要があります。 double ( (double)o ) にキャストし、それを int .

の結果はどうなるのでしょうか。

double e = 2.718281828459045;
double d = e;
object o1 = d;
object o2 = e;
Console.WriteLine(d == e);
Console.WriteLine(o1 == o2);

ちょっと考えてから次の文章に進んでください。

もし、あなたが TrueFalse すごい 待てよ、なんだ?それは == 参照型では参照等価を使用し、基礎となる値が等しいかどうかではなく、参照先が等しいかどうかをチェックします。これは危険なほど簡単なミスです。おそらくもっと微妙なのは

double e = 2.718281828459045;
object o1 = e;
object o2 = e;
Console.WriteLine(o1 == o2);

も表示されます。 False !

と言った方がいい。

Console.WriteLine(o1.Equals(o2));

と表示され、ありがたいことに True .

最後にもうひとつ、微妙なことを。

[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);

出力はどのようになりますか?それは、人それぞれです。もし Pointstruct であれば、出力は 1 しかし、もし Pointclass であれば、出力は 2 ! ボックス化変換はボックス化された値のコピーを作成し、動作の違いを説明します。