たとえば、関数プロトタイプは次のとおりです。
void set<V>(Type a, V b);
そして、私たちはそれを次のように呼びます:
int a;
list<int> b;
set<List<int>>(a,b);
(パラメーターと引数の違いを思い出させるために、答えの前に付けます。パラメーターは何かの「プレースホルダー」であり、引数はパラメーターを埋める値です。(したがって、「パラメーター引数」という用語)たとえば、クラスList<TFoo>
には。というパラメータがありますがTFoo
、インスタンスにはパラメータList<String>
の引数があります。)String
TFoo
タイプは「一般的」または「具体的」(つまり非一般的)のいずれかです。
ジェネリック型パラメーターの引数は、具体的またはジェネリックの任意の型にすることができます。すべてのパラメーターが具象型引数で埋められているジェネリック型は、それ自体が具象になります。List<String>
は具体的であるため具体的ですが、型パラメータであるため具体String
的でList<TFoo>
はありません。TFoo
したがって、これにより、ジェネリッククラスがジェネリック形式または具象形式のいずれかで再帰的にネストできることがわかりやすくなります。もちろん、ジェネリッククラスまたはメソッドコンテキスト内でのみジェネリックフォームを使用できます。たとえば、以下は完全に合法です。
private static IEnumerable<List<Dictionary<String,Int32>>> foo = new Collection<List<Dictionary<String,Int32>>>(); // this is completely concrete
static void DoSomething<TBaz>(IEnumerable<List<Dictionary<TBaz,Int32>>> baz) { // this is generic because TBaz is not specified
List<TBaz> someList = new List<TBaz>(); // you can use the undefined TBaz because it's listed in the generic method's type arguments.
}
static void Main() {
DoSomething( foo ); // the compiler will infer TBaz from the String argument used in the foo field
}
私はあなたがあなたがType a
特定することができるかどうか尋ねようとしていると思いますV
...
それがあなたの質問なら、そうです、あなたは次のようにメソッドを定義する必要があります:
void set<V>(V a, List<V> b)
a
タイプであることが意図されている場合は、タイプパラメータとして許可されるType
という質問に「はい」と答えます。List<int>
ただし、a
isint
とnotであるため、例はコンパイルされませんType
。
次のような一般的な制約を使用できます。
void set<TList, TElement>(TElement value, TList list)
where TList: IList<TElement>;