2009-03-28 14 views
27

C#/ VB.NETでのジェネリックスの使用例とジェネリックの使い方を教えてください。.NETでのGenericsの使用例(C#/ VB.NET)

+4

この質問は –

+0

あなたがオープンジェネリックまたはクローズジェネリックについて話しているあまりにも一般的なのですか?主に、どのようにして1つの「使用」するのか、あるいはどのようにして1つ「作る」のだろうか?または両方? – Joseph

+0

sambo99が言ったこと - あまりにもローカライズされた "補完するにはあまりにも曖昧な"必要がある – annakata

答えて

60

単純に、あなたは一般的なビットを示すために、余分なタグをタイプまたはメソッドを宣言します。

class Foo<T> { 
    public Foo(T value) { 
     Value = value; 
    } 
    public T Value {get;private set;} 
} 

を上記のTが呼び出し元によって提供される「Tの」ジェネリック型Fooを、定義されています。一つだけ存在する場合は慣例により、ジェネリック型引数はTは結構です、T.で始まる - それ以外の場合は有効にそれらすべてに名前を付ける:TSourceTValueTListType

は、C++のテンプレートとは異なり、.NETのジェネリックは、ランタイムによって提供されているなど(ではありませんコンパイラトリック)。たとえば:

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

すべてT sが上記でintに置き換えられました。必要な場合は、制約のジェネリック引数を制限することができます。今すぐ

class Foo<T> where T : struct {} 

Foo<string>は、コンパイルを拒否します - stringは、構造体(値型)ではないとして。有効な制約は以下のとおりです。

T : class // reference-type (class/interface/delegate) 
T : struct // value-type except Nullable<T> 
T : new() // has a public parameterless constructor 
T : SomeClass // is SomeClass or inherited from SomeClass 
T : ISomeInterface // implements ISomeInterface 

制約はまた、例えば、他のジェネリック型引数を含むことができる:

public struct KeyValuePair<TKey,TValue> {...} 

他のものを:あなたが必要として

T : IComparable<T> // or another type argument 

あなたはできるだけ多くの一般的な引数を持つことができます注記:

  • タティックメンバーなどはごとにと定義されているので、Foo<int>の静的フィールドはFoo<float>の静的フィールドとは別です。
  • 方法が一般的すぎることができます - あなたは親から
  • ネストされた型がジェネリック型を継承明確にすることができなくなりますよう、クラスが使用するのと同じ名前を使用して回避しよう
  • 例えば

class Foo<T> { 
    class Bar<TInner> {} // is effectively Bar<T,TInner>, for the outer T 
} 
+0

すばらしい答え。好奇心から(ジェネリックの新機能)、なぜクラス名の後ろにを含める必要がありますか? –

+0

@JᴀʏMᴇᴇは、定義がフックアップされるまでプレースホルダーとして使用されます。 –

+1

@JᴀʏMyou好きな場合は、 ''にすることができます。 「T」は単に「一般的なもの」のための慣習です。したがって、 'List 'は 'T '型の要素のリストです。 'Dictionary 'は 'TKey'タイプのキーと' TValue'タイプの値を持つ辞書です –

6

例1:あなたはトリプルクラス

Class Triple<T1, T2, T3> 
{ 
    T1 _first; 
    T2 _second; 
    T3 _Third; 
} 

エクサを作成したいですmple 2:ジェネリック医薬品のための最も一般的な理由と使用例は、前述のMSDNのドキュメントに記述されている特定のデータタイプ

static public class EnumHelper<T> 
{ 
    static public T Parse(string value) 
    { 
     return (T)Enum.Parse(typeof(T), value); 
    } 
} 
3

のための任意の列挙型の値を解析するヘルパークラス。私が追加したいジェネリックの1つの利点は、開発プロセスのツールサポートを強化できることです。 Visual StudioやReSharperに統合されているようなリファクタリングツールは、コーディング中に支援を提供する静的型分析に依存しています。ジェネリックスは通常、オブジェクトモデルに型情報を追加するので、解析したり、コーディングに役立つツールについての情報があります。

概念レベルでは、ジェネリックスはアプリケーションドメインとは独立した「クロスカッティング」の問題を解決するのに役立ちます。あなたが金融アプリケーションや本屋を開発しているかどうかに関わらず、あなたは早急に、アカウントや書籍など、何かのコレクションを維持する必要があります。そのようなコレクションの実装は、通常、それらのコレクションで維持されるべきものについて、ほとんど何も知らない必要があります。したがって、.NETフレームワークに付属しているジェネリックコレクションは、ジェネリックユースケースの主な例です。

4

ジェネリックの一般的な使い方は、強く型付けされたコレクションクラスです。従来は、すべてのコレクションクラスにオブジェクトを渡す必要があり、照会するとオブジェクトが返されます。あなた自身ですべてのタイプ変換を処理しなければなりませんでした。ジェネリックで、あなたはそれをする必要はありません。 List(Of Integer)を持つことができ、値を要求すると整数が得られます。あなたは整数に変換する必要があるオブジェクトを取得しません。

3
private void button1_Click_1(object sender, RoutedEventArgs e) 
    { 
     TextValue<string, int> foo = new TextValue<string, int>("",0); 
     foo.Text = "Hi there"; 
     foo.Value = 3995; 
     MessageBox.Show(foo.Text); 
    } 

    class TextValue<TText, TValue> 
    { 
     public TextValue(TText text, TValue value) 
     { 
      Text = text; 
      Value = value; 
     } 
     public TText Text { get; set; } 
     public TValue Value { get; set; } 
    } 
0
private void button1_Click_1(object sender, RoutedEventArgs e) 
    { 
     TextValue<string, int> foo; 
     List<TextValue<string, int>> listTextValue = new List<TextValue<string, int>>(); 
     for (int k = 0; k < 5; ++k) 
     { 
      foo = new TextValue<string, int>("",0); 
      foo.Text = k.ToString(); 
      foo.Value = k; 
      listTextValue.Add(foo); 
      otherList. 
      MessageBox.Show(foo.Text); 
     } 

    } 

    class TextValue<TText, TValue> 
    { 
     public TextValue(TText text, TValue value){Text = text; Value = value;} 
     public TText Text { get; set; } 
     public TValue Value { get; set; } 
    } 
1

基本的な例は次のようになります。

class Other{ 
class Generic<T> 
{ 
    void met1(T x); 
} 
static void Main() 
{ 
    Generic<int> g = new Generic<int>(); 
    Generic<string> s = new Generic<string>(); 
} 
}