[解決済み] なぜC#ではボクシングとアンボクシングが必要なのか?
質問
なぜ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);
ちょっと考えてから次の文章に進んでください。
もし、あなたが
True
と
False
すごい 待てよ、なんだ?それは
==
参照型では参照等価を使用し、基礎となる値が等しいかどうかではなく、参照先が等しいかどうかをチェックします。これは危険なほど簡単なミスです。おそらくもっと微妙なのは
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);
出力はどのようになりますか?それは、人それぞれです。もし
Point
は
struct
であれば、出力は
1
しかし、もし
Point
は
class
であれば、出力は
2
! ボックス化変換はボックス化された値のコピーを作成し、動作の違いを説明します。
関連
-
[解決済み] C#のStringとstringの違いは何ですか?
-
[解決済み] C#の正しいバージョン番号を教えてください。
-
[解決済み] ディープクローンオブジェクト
-
[解決済み] 複数の例外を一度にキャッチする?
-
[解決済み] C#で文字列のエンコーディングを手動で指定せずに、一貫性のあるバイト表現を得るには?
-
[解決済み] IDisposable インターフェースの正しい使用法
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] 特定のプロパティに対するLINQのDistinct()
-
[解決済み] キーワード「ref」と「out」の違いは何ですか?
-
[解決済み】大文字・小文字を区別しない「Contains(string)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C# ASP.NET使用時に「WebClientのリクエスト中に例外が発生しました。
-
[解決済み】Unity3DでOnTriggerEnterが動作しない件
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み】Socket.Selectがエラー "An operation was attempted on something that is not a socket" を返す。
-
[解決済み】EF 5 Enable-Migrations : アセンブリにコンテキストタイプが見つかりませんでした
-
[解決済み】IntPtrとは一体何なのか?
-
[解決済み】ファイルやアセンブリ、またはその依存関係の1つをロードできませんでした。
-
[解決済み] Nullable<T>.HasValueとNullable<T> != nullの違いは何ですか?
-
[解決済み] C#のプリミティブの==とEquals()の違いは何ですか?
-
[解決済み] 再定義とは何ですか?