2009-04-28 5 views
7

ジェネリックスを継承で使用する場合と、その逆の場合の状況とその関連する利点は何ですか?ジェネリックスと継承を適切に使用するのはいつですか?

回答ありがとうございます。以下に示すように、私はクラスを持っている :

class InformationReturn<T> where T : Info 
{ 
    InformationReturn(Employee employee, List<T>) { ... } 
} 

今私はInformationReturn引数を取るリポジトリがあるとし、

は、私は私ができる最善のように、この質問のための動機を述べるしようとするつもりですInfoオブジェクトTのタイプに応じてDB内の異なるフィールドをストロークさせる必要があります。 T型のためにそれぞれ異なるリポジトリを作成する方が良いですか?タイプを決定するためにリフレクションを使用する1つのリポジトリ。ジェネリックの上/に継承機能を使用するより良い方法がありますか?

注::他のクライアントコードは、Tのタイプに基づいて異なって動作する必要があります。

答えて

4

は、彼らは完全に本当にさまざまなアイデアです。ジェネリックスを使用すると、一般的な方法で一般的な「特定の」機能(擬態語の発音の危険性がある)を宣言することができます。 List<int>は、内部に保持されているデータの種類以外に、List<string>とはまったく異なる機能を持ちません。

継承が同じことを行うために使用することができますが、私はその後Listクラス、IntListとそれを継承StringListクラスを作成することができます。私はこれらの2つのクラスを完全に異なった機能にすることも、もう1つの機能を他の機能で利用できないようにすることもできます。

編集

の質問に編集を確認した後、答えはsortof「それが依存」です。 LINQ to SQLとEntity Frameworkの両方は、ジェネリックを使用した反射検査と、厳密に型指定されたエンティティクラスと他のリポジトリクラスの両方の組み合わせです。あなたは確かにあなたが見ているアプローチを取ることができます。ただ、一般的には、反射や他の何かで解決できる問題は、「何か他のもの」によって解決されるともっと速くなるでしょう。パフォーマンス、保守性、可読性、および信頼性の間でどの程度のトレードオフが必要なのかがわかります。

+0

この答えは、行動に差がないとき、私はジェネリックを使用する必要があります指すように私を助けましたそうでなければ継承、ありがとう。 私は私の動機についてより明確になるように質問を修正しました。 – Laz

10

ジェネリックと継承は2つの別個のものです。継承はOOPの概念であり、ジェネリックは、コンパイル時に型パラメータを公開するCLRの機能です。

継承とジェネリックは、実際にはかなりよく機能します。

継承:

継承は私が1種類作成することができます:

class Pen { } 

をし、後でPenを拡張し、別のタイプの作成:私ができるので、これは便利です

class FountainPen : Pen { } 

を基底クラスのすべての状態と動作を再利用し、新しい動作や状態を公開するFountainPen。継承により、より特定のバージョンの既存のタイプを迅速に作成することができます。

ジェネリック:私はFoo<T>を使用するときに、私はTの種類は、提供することで、どうなるかを指定することができます今

class Foo<T> 
{ 
    public T Bar { get; set; } 
} 

ジェネリックは、私がこのようなタイプを作成してみましょうCLR機能ですジェネリック型引数:

Foo<int> foo = new Foo<int>(); 

今、私が指定したので、私が作成したばかりのオブジェクトに対しては、はintとなります。と宣言されているので、Foo.Barのタイプはintとなります。

+3

しかし、それぞれをいつ使うべきですか? –

+1

pedantryの噛み砕きビット:ジェネリック型*引数*を指定します。つまり、Tは型パラメータ、intは型引数です。それが編集の価値があるかどうかを決めることができます:) –

+0

修正済み!それを指摘してくれてありがとう、pedantryは決して歓迎されていません - 良さは私がそれ自身の多くを扱うことを知っています:) –

3

継承は、型指定されたデータ(List of T、T of Processorなど)に作用するコンテナを作成することについて、 "is-a"(カエルは動物です)です。それらはであり、互いに排他的ではありませんです。

したい場合は、これを持つことができます

public class Base<T> 
{ 

} 

public class Derived : Base<Foo> 
{ 

} 
+0

そして実際に、あなたは一般的なインターフェイスを持つことができます。パブリックインターフェイスIBASE - >パブリック抽象基本:IBASE - 派生> publicクラス:基本

4

さまざまなタイプ(Add、Remove、Count)に同じ機能だけを適用したい場合はジェネリックスを使うべきだと思います。同じ方法で実装されます。継承は、同じ機能(GetResponse)が必要なときですが、異なる方法で実装する必要がある場合です。

+0

IMO、これは実際にこの質問に対する最良の答えです!約20分間SEを検索した後に.. – Pingi

7

ジェネリックを使用して、アルゴリズムまたはタイプの動作を指定します。この動作は、「未知のタイプ」という言葉で表現され、その未知のタイプに関して強く型付けされたAPIを保持します。未知のタイプは、型パラメータとして知られており、このようなコードで表現される:

public class List<T> 
{ 
    public void Add(T item) 
} 

(ETC) - ここでT型パラメータです。一般的な方法は似ています:コードを呼び出す

public void Foo<T>(T item) 

型引数には、例えばで動作するように望んでいるを指定します

List<string> list = new List<string>(); 
list.Add("hi"); 

タイプの動作を特化するために継承を使用します。

あなたは、未知のクラスの多くのスタイルに適用できる「テンプレート」を作成したいとき、私は本当に...彼らはお互いに代わるいる多くの場所で

+0

Downvoters:理由を教えてください... –

+1

+1 "generic programming"の簡潔な定義については、 –

+3

私はあなたにdownvoteしなかったが、あなたの答えは役に立たないです。 OPは明らかに.NETの新機能であり、あなたの非常に短く簡潔な辞書の定義は、彼/彼女の混乱を解消するためにほとんど役に立たないでしょう。 – BFree

4

使用ジェネリックを考えることはできません。例えば。コレクションには???ジェネリック医薬品の良い候補者です。継承は、子どもたちがその概念の延長線上にあるという根底にある概念を持っているときのためのものです。

私の一般的なルール

  • あなたはジェネリックのためにそのおそらく時間、その後、あなたのコード内のオブジェクトとしてproperitesの定義を開始し、多くの鋳造入力した場合。
  • "上位コンセプト"と派生クラス、そしてその継承に対してプログラムしたい場合は、
  • あなたのクラスがコンフェクトクラスをラップしたり、そのクラスのジェネリックスで動作する場合は、
  • 未知の "まだ定義されていない"クラスの仕様に頼っているのであれば、おそらくジェネリックの方が良いでしょう。
  • 派生クラスが "is a"の場合、通常は継承
  • スーパークラスが "some x"を使用していれば、そのジェネリックスです。
+0

今すぐコメントできます! – Vaccano

関連する問題