ボクシング/ボクシングは、後期または早期の拘束力を通じて実装されていますか(つまり、実行時またはCompiletime)?
質問
例:
int i=10;
object o = i; //late or early??
同様に、
object o = "11";
int i = (int)o;//late or early??
解決
ボクシングとアンボクシングは、後期または早期のバインディングを通じて実装されていますか?つまり、バインディングは実行時に行われますか、それともコンパイル時間ですか?
私は質問に少し混乱しています。 「バインディング」は通常、何らかの分析の結果を意味するために使用されます。 「初期のバインディング」とは通常、コンパイル時に何らかの名前が何らかの方法スロットに関連付けられていることを意味します。 「後期バインディング」は、実行時に名前をスロットに関連付けます。ボクシングの文脈でここで「バインディング」とはどういう意味ですか?
遅いバインディングは、メソッドとメソッドの呼び出しのみで作用し、割り当て操作/タイプ変換では発生していると言うことを意味します。動的バインディングを実装するために、基本クラス変数を使用して派生オブジェクトを参照します。
それはまさに私が意味したことではありません。私は、早期結合と後期結合の違いを示す標準的な例としてメソッド呼び出しを使用していました。私は今あなたの主張をよく見ています。変換の実行方法を正確に決定する分析は、実行時またはコンパイル時にも実行でき、したがって、ある意味では「遅い結合」または「早期結合」の形態でもあります。
この変換の例として考えましょう:
int x = Whatever();
short y = (short)x;
その明示的な変換は、コンパイル時に完全に「バインド」されます。コンパイラは、オペランドがINTであり、ターゲットタイプが短いこと、4バイトのINTを2バイトの短いショートに切り捨てることによって変換が実行されることを知っています。もちろん、変換は実際に実行時に実行されます。
それでは、少し明確にしましょう:
int x = Whatever();
short y = checked((short)x);
明示的な変換は、コンパイル時に再びバインドされます。操作の実行方法はわかっています。しかし、私たちもそれを知っています 実行時に、int値がチェックされ、短いものに収まることを確認します.
それはあなたの本の中で「遅いバインディング」としてカウントされますか?分析の一部はコンパイル時に実行されますが、分析の一部は実行時に実行されます。
それでは、ボクシングを考えてみましょう:
int x = Whatever();
object q = x;
これは、コンパイル時に完全に分析されます。コンパイラは、qがオブジェクトであり、xがintであることを知っているため、実行時にintをボックスするように指示を発行する必要があります。
ボクシングアンボックスはどうですか?
int x = Whatever();
object q = x;
int y = (int)q;
コンパイル時間でどのような分析が行われますか?コンパイル時間で私たちが知っているのは、それがボックス化されていない変換であるということです。実際のタイプチェックは実行時に行われます。それは、ランタイムでタイプチェックが実行されるため、遅いバインディングの定義により実行されるため、「遅いバインディング」の形式ですか?
これはどう?
int x = Whatever();
object q = x;
int y = (short)q;
それは実行時に例外を投げます。コンパイル時に、それがボックス化されていない変換であることがわかります。実行時には、「遅いバインディング」を行いません。むしろ、「intを短くすることを解き放ちます。例外を投げようとしています」と言います。箱入りTは、Tまたは無視可能なTに対してのみボックス化できません。
それでは、「早期バウンド」または「遅い縛られた」ボックス化されていないのでしょうか?コンパイル時に、それがボックス化されていない変換であることを知っているという意味で、それは早期に縛られています。実行時にタイプチェックを行うという意味で遅れて縛られています。コンパイル時には、int-short変換のために行われたであろうタイプ分析を実行時に再現しないという意味で遅れて拘束されません。
これはどうですか?
int x = Whatever();
object q = x;
int y = Convert.ToInt16(q);
また
int x = Whatever();
dynamic q = x;
int y = (int)q;
今、私たち 行う 実行時にすべての分析を実行します。どちらの場合も、実行時にQのタイプ分析を行い、Qがボックス付きINTであると判断し、変換を「後期バインド」します。
それはすべて明確ですか?あなたの質問に答えるのは難しいです。なぜなら、それはあなたがコンバージョンを「遅く結合」することの意味について少し曖昧だからです。分析のどの部分があなたへの「バインディング」ですか?
他のヒント
それがあなたが探しているものである場合、ボクシングはコンパイル時にILの指示に焼き付けられます。
元のタイプ以外のタイプに箱を開けようとすると、例外がスローされます。 ex#1それは、暗黙的にボックスにたまたま(ref type type型型cast)だけです。 Ex#2実行時に無効なキャストが吹き飛ばされます。
早期または遅いバインディングがどのように写真に入ってくるかはわかりません。
コンパイラ ILで見ることができるボクシングの指示を発します。指定されたコード
int item = 10;
object obj = item;
item = (int)obj;
あなたは次のようなものにコンパイルします
IL_0000: ldc.i4.s 0A
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: box System.Int32
IL_0009: stloc.1
IL_000A: ldloc.1
IL_000B: unbox.any System.Int32
IL_0010: stloc.0
2番目のバージョンでは、それは爆発するだけです。型文字列のオブジェクトは、整数にキャストすることはできません。
C#は、実行時に実行される指示をコンパイルします。
ボクシングには、(思いやりのない)ランタイムコストが必要です。ボクシングとボクシングは、ランタイムエラーを引き起こす可能性があります(例として、「int i =(int)o」が示すように)。
「後期バインディング」vs「早期バインディング」は、何かが「動的」であることを意味します(たとえば、オブジェクトの仮想方法のランタイムバインディング)。この場合、ボクシングは「固定」です。ですから、「初期のバインディング」だと言えると思います。