私は本を読んでいて、ジェネリックを使用すると、プログラマーは、例えばStack
.
スタック(ジェネリックではない)は参照型変数のみを保持でき、キャストのみでボクシングは行われないため、完全には正しくないと思います。
編集:私の知る限り、ボクシングは値型からオブジェクトへの変換のみに関連しています。それは正しいですか、それとも何か不足していますか?
参照をボックス化する必要がStack<SomeReferenceType>
ないという理由だけで、(非)ボックス化が発生しません。参照は、.NETで型が機能する「通常の」方法です-object
結局のところ、参照型です。
編集:あなたの明確な質問は、あなたがの非ジェネリックバリアントについて話していることを明らかにしていますStack
。参照型はボックス化されない(実際にはボックス化できない)ため、このバリアントは参照型をボックス化およびボックス化解除する必要がないと言っているのは正しいです。object
のサブクラスのインスタンスをStack
、アイテムを取り出してインスタンスのアスペクト(すべてobject
のsに一般的ではない)を使用しようとすると、にキャストする必要があることも正しいです。サブクラス。
(参照型の場合)概念的には「キャスト」について説明しますobject
が、これは実際の操作に対応していないことに注意してください。(オブジェクトまたは他のスーパークラスへの)アップキャストは無料です。マシンがダウンキャストが有効であることを確認する必要があるのは、ダウンキャストです。したがって、の非ジェネリックバリアントをStack
参照型のインスタンスで埋めるだけで効率的です。オーバーヘッドは、から抽出してより具体的なタイプにキャストStack
する場合にのみ発生します。
(ダウン)キャスティングはかなり安いですが、無料ではありません。参照型の場合でも、値を再度抽出する必要がある場合は、ジェネリックコレクションが非ジェネリックコレクションよりもわずかに優れていることを期待してください。ただし、(いつものように)数CPUサイクルに関心がない場合でも、バグをより早く発見するのに役立つため、ジェネリックコレクションの方が適しています。誤って間違ったタイプのアイテムを非ジェネリックリストに追加した場合は、抽出して使用するまで、警告は表示されず、エラーも表示されませんその値は、はるかに後の(またはまったくない)可能性があり、別のコードファイルまたは別のアセンブリにある可能性があります。このようなエラーのデバッグは、特にコードに多数のレイヤーがあり、コレクションに直接アクセスするレイヤーにエラーがない場合は、非常に面倒です。
対照的に、間違ったタイプの値を追加しようとすると、ジェネリックコレクションはコンパイルされません。また、型に安全でないインターフェイスを実装する必要があり、コンパイラがエラーをキャッチできない場合でもInvalidCastException
、コレクションにアイテムを追加すると(バグの根本原因の近くで)がスローされるという利点があります。抽出後ではなく(バグの根本的な原因からはほど遠い)。コードにはバグがあり、一見無関係なコードで奇妙な例外を取得するのではなく、迅速かつ安価にそれらを見つけたいと考えています。
実際、非ジェネリックコレクションを使用する唯一の理由は、それらの使用を必要とするレガシーAPIと相互運用することです。
問題は、Stack
クラスに入れたオブジェクトをとして保存することですobject
。つまり、スタックに何かを置くたびに、それはオブジェクトにボックス化され、スタックからオブジェクトで使用するたびに、正しいタイプを取得するために、もう一度ボックス化を解除する必要があります。