どのようなJavaの利用-サイトの分散比較C#'s宣言サイト分散?
質問
私の理解であることを指定する分散のためのジェネリック医薬品のC#させることができることの型宣言部レベル:がんの作成リースタイプで、指定の差異の型引数になります。Javaでは、一方で、分散が指定される汎用的な使用していを作成したときに変数の一部は、総称型を指定しまうタイプの引数が変動する可能性も存在する。
その是非に各オプションか?
解決
私はC#とJavaのジェネリックは、他の多くの方法が異なっている間、それらの違いはほとんど差異に直交している、以来、宣言サイトと利用サイトの分散の違いを答えるつもりです。
まず最初に、もし私を覚えて正しく使用して、サイトの分散宣言サイトの分散より厳密に、より強力である(簡潔の費用であるが)、または少なくともJavaのワイルドカードは、(これは、使用部位の差異よりも、実際にはより強力である)されています。この増大した電力は、C#やJavaのようなステートフルな構築物が頻繁に使用される言語のために特に有用である(しかし、スカラはるかに少ないので、その標準リストは不変であり、特に以来)。 List<E>
(またはIList<E>
)を考えてみましょう。それがためのメソッドを持っているので、両方の追加EさんとEさんは、それがEに対して不変である、と宣言サイトの分散が使用できないようになって。しかし、利用サイトの分散であなただけList<+Number>
の反変サブセットを取得するためにList
とList<-Number>
の共変サブセットを取得するためにList
を言うことができます。宣言サイトの言語でライブラリーの設計者は、各サブセットのために(あなたはクラスの多重継承を許可した場合またはクラス)とそれらのインターフェイスを拡張List
持つ別々のインターフェースを作成する必要があります。ライブラリ設計者は、この(C#のIEnumerable
だけIList
の共変部分の小さなサブセットをないことに注意してください)を行わない場合は、運のうちだと、あなたはなし言語で行う必要があり、同じ口論に頼る必要があり分散の任意の並べ替えます。
だから宣言サイトの継承を超える利用サイトの継承の利点です。利用サイトの継承オーバー宣言サイトの継承の利点は、基本的には、(設計者がその共変と反変の部分にすべてのクラス/インタフェースを分離する努力を経て提供される)ユーザーのために簡潔です。 IEnumerable
またはIterator
のようなもののために、それの素敵な共分散にあなたがインターフェイスを使用して一つ一つの時間を指定する必要がありません。 Javaは(Javaのソリューションは、基本的には理想的であるためbivarianceを除く)長い構文を使用して、この特に迷惑を作っています。
もちろん、これら二つの言語機能を共存させることができます。 (例えばIEnumerable
/ Iterator
のように)自然に共変または反変である型パラメータの宣言ように宣言されます。 (例えば(I)List
のように)自然に不変である型パラメータについては、種類の分散のあなたは、あなたがそれを使用するたびに欲しいものを宣言します。それはちょうど混乱物事を作るとしてだけで宣言サイトの分散を持つ引数の使用部位の分散を指定しないでください。
があり(例えば、ワイルドカードは、実際に使用サイトの分散よりも強力であるかのように)私はに行っていない他のより詳細な問題がありますが、私はこれがあなたのコンテンツにあなたの質問に答える願っています。私は、私は、使用部位の差異に偏って、私はプログラマとし、言語研究者と私の議論に出ているの両方の主要な利点を描写しようとしています。
認めますよ他のヒント
ほとんどの人も好宣言サイトの分散ができ ユーザー 図書館(中で少し硬くの図書館で開発者は思うので、図書館のプロフィールを考える分散関わらず、差異が実際に書かれています。)
が約への同意が必要となるJavaやC#例の言語でデザイン。
ながら Java た分散権は、独立して働くのJVMでの対応VMの改善Java5タイプ-消去、利用サイトの分散が利用少し面倒に特定の実装型-消去からの関心はメディアです。
C#'sモデルの宣言-サイトの分散に負担のかから、ユーザーの図書館が導入reifiedジェネリック医薬品では基本的には分散ルールのVM.今日でもな支援co-/contravarianceころの下位互換性のreifiedコレクションクラスは分割のプログラマの二つのキャンプ).
このポージングの難しい制限すべての言語を対象に、CLR、その代替プログラミング言語り活き活きのJVMではなく、このCLRは"素晴らしい。
見てみましょう Scala:Scalaは完全にオブジェクト指向機能性ハイブリッドのJVM.彼らは利用の停止、消去などをJavaでの実施のジェネリック医薬品の宣言サイト)に分散して、よりわかりやすく、より簡単、より強力なJava、C#'s")、そのVMになるルールをどう分散してます。のスカーラコンパイラのチェックの分散ファイルは、取を拒否することができ健全なソースコード コンパイル時に の代わりに投げる例外をランタイム時において、なによる.クラスファイルでシームレスに利用するJava.
るうえでひとつ難点があるの宣言サイトに分散されているようで作型推論く場合があります。
同時にスカーラで使用プリミティブ型なボクシングしてコレクションのようにクライアントまで、フルのC#の @specialized
注釈における動作確認を迅速に行えるスカーラコンパイラを一つまたは複数の追加の実装クラスやメソッドを専門に要求されたプリミティブタイプです。
Scalaでも"ほとんど"reifyジェネリック医薬品を使用マニフェストを取得するの種類実行時のようにクライアントまで、フルのC#.
デメリットのJavaスタイルジェネリック医薬品
一つの結論は、javaバージョンのみになりますので参照型(またはboxed値)が必要とな価値です。IMOの最大の欠点でを防止し高性能ジェネリック医薬品は多くのシナリオのもとに手書きの専門です。
を保証するものではありません、不変量"のようなこのリストだけが含まれます物体のタイプx"およびニーズの実行時のチェックでゲッター.汎用タイプも存在します。
使用時の反射なのでこれ位かなと思いましたのインスタンスは、汎用オブジェクトの汎用パラメータの良くなっています。
メJavaスタイルジェネリック医薬品
きない分散/キャストと異なる汎用パラメータ。
のJava:1.0以来の異なる構文を持つJava 5.壊れた共変配列から使用現場の分散ジェネリック。ジェネリック医薬品のない実行時の型情報。
C#:使用サイトの分散ジェネリックC#2.0以降。 C#4.0の宣言サイト分散を追加しました。 1.0(Javaのと同じ問題)ので、異なる構文を持つ共変配列を破壊しました。型情報は、コンパイル時に失われないことを意味ジェネリックを「具体化」ます。
スカラ:(少なくとも2008年以降)の言語の初期バージョン以来の両方を使用-サイト/宣言サイトの分散。あなたが同じジェネリック構文を使用し、分散ルールを入力するよう配列は、別の言語機能ではありません。あなたは、Javaコードと比較して同等以上の実行時のパフォーマンスを得るように、特定のコレクションは、JVMアレイとVMレベルで実装されています。
のC#/ Javaの配列型の安全性の問題について詳しく説明するには:あなたはペットの[に犬を[]にキャスト]や猫を追加し、コンパイル時にキャッチされていないランタイムエラーをトリガすることができます。 Scalaはこれを正しく実装します。