web-dev-qa-db-ja.com

C#で<T>が意味するもの

私はC#が初めてで、受け取ったプロジェクトのコードを直接変更することに没頭しています。しかし、私はこのようなコードを見続けています:

class SampleCollection<T>

そして私は何の意味を理解することはできません

<T> 

意味も何とも呼ばれません。

誰かがこのコンセプトが何と呼ばれているのかを私に教えてくれたら、オンラインで検索できます。しかし、私は今のところ無知です。

75
Yash Desai

Generic Type Parameter です。

ジェネリック型パラメーターを使用すると、メソッドまたはクラス宣言で具体的な型を指定せずに、コンパイル時にメソッドに任意の型Tを指定できます。

例えば:

public T[] Reverse<T>(T[] array)
{
    var result = new T[array.Length];
    int j=0;
    for(int i=array.Length - 1; i>= 0; i--)
    {
        result[j] = array[i];
        j++;
    }
    return result;
}

配列内の要素を反転します。ここで重要な点は、配列要素は任意の型であり、関数は引き続き機能するということです。メソッド呼び出しでタイプを指定します。型の安全性はまだ保証されています。

したがって、文字列の配列を逆にするには:

string[] array = new string[] { "1", "2", "3", "4", "5" };
var result = reverse(array);

result of { "5", "4", "3", "2", "1" }の文字列配列を生成します

これは、次のような通常の(非ジェネリック)メソッドを呼び出した場合と同じ効果があります。

public string[] Reverse(string[] array)
{
    var result = new string[array.Length];
    int j=0;
    for(int i=array.Length - 1; i >= 0; i--)
    {
        result[j] = array[i];
        j++;
    }
    return result;
}

コンパイラは、arrayに文字列が含まれていることを確認するため、文字列の配列を返します。タイプstringは、Tタイプパラメーターの代わりに使用されます。


ジェネリック型パラメーターを使用して、ジェネリッククラスを作成することもできます。 SampleCollection<T>を指定した例では、Tは任意の型のプレースホルダーです。 SampleCollectionはオブジェクトのコレクションを表すことができ、コレクションの作成時に指定するタイプを意味します。

そう:

var collection = new SampleCollection<string>();

文字列を保持できるコレクションを作成します。上記のReverseメソッドは、多少異なる形式で、コレクションのメンバーを逆にするために使用できます。

97
Robert Harvey

これは、ジェネリック型パラメーター Genericsdocumentation を参照してください。

Tは予約キーワードではありません。 Tまたは任意の名前は、型パラメーターを意味します。次の方法を確認してください(単純な例として)。

T GetDefault<T>()
{
    return default(T);
}

戻り型はTであることに注意してください。このメソッドを使用すると、メソッドを次のように呼び出すことで、任意のタイプのデフォルト値を取得できます。

GetDefault<int>(); // 0
GetDefault<string>(); // null
GetDefault<DateTime>(); // 01/01/0001 00:00:00
GetDefault<TimeSpan>(); // 00:00:00

.NETはコレクションでジェネリックを使用します...例:

List<int> integerList = new List<int>();

この方法では、クラスはT型(この場合はint)でインスタンス化され、要素を追加するメソッドは次のように記述されるため、整数のみを受け入れるリストが作成されます。

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

ジェネリックに関する詳細情報。

タイプTのスコープを制限できます。

次の例では、クラスである型でのみメソッドを呼び出すことができます。

void Foo<T>(T item) where T: class
{
}

次の例では、Circleであるか、継承するタイプのメソッドのみを呼び出すことができます。

void Foo<T>(T item) where T: Circle
{
}

また、パラメータなしのコンストラクタがある場合、Tのインスタンスを作成できるというnew()があります。次の例では、TCircleとして扱われ、インテリセンスが得られます...

void Foo<T>(T item) where T: Circle, new()
{
    T newCircle = new T();
}

Tは型パラメーターであるため、そこからオブジェクトTypeを取得できます。 Typeを使用すると、リフレクションを使用できます...

void Foo<T>(T item) where T: class
{
    Type type = typeof(T);
}

より複雑な例として、ToDictionaryまたはその他のLinqメソッドの署名を確認してください。

public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);

Tはありませんが、TKeyTSourceはあります。上記のように、常に型パラメータに接頭辞Tを付けることを推奨します。

TSomethingFooという名前を付けることもできます。

22
BrunoLM

この機能はジェネリックとして知られています。 http://msdn.Microsoft.com/en-us/library/512aeb7t(v = vs.100).aspx

この例は、特定のタイプのアイテムのコレクションを作成することです。

class MyArray<T>
{
    T[] array = new T[10];

    public T GetItem(int index)
    {
        return array[index];
    }
}

コードでは、次のようなことができます。

MyArray<int> = new MyArray<int>();

この場合、T[] arrayint[] arrayのように機能し、public T GetItempublic int GetItemのように機能します。

8
Kendall Frey