1. 嵌套的泛型类型或方法的实例化:
class GenericClass<T>
{
public class NestedGenericClass<T2>
{
...
}
public void GenericMethod<T2>(T2 t)
{
...
}
}
为了通过Reflection实例化以上的NestedGenericClass<>和GenericMethod<>,必须照顾到它们的包含类,即GenericClass<>。
通常以为以下的过程会完成实例化到genNestedCls类型变量中:
Type gcls = typeof("GenericClass<>");
Type genGcls = gc.MakeGenericClass(typeof(int));
Type nestedCls = genGc.GetNestedType("NestedGenericClass`1");
Type genNestedCls = nestedCls.MakeGenericClass(typeof(double));
但事实上在运行时候,执行最后一句时就会报泛型参数不匹配错误,而正确的做法应该是:
Type genNestedCls = nestedCls.MakeGenericClass(typeof(int), typeof(double));
即将包含类的泛型参数也代入,而事实上,也可以不用泛型参数实例化的包含类进行构建内部嵌套的类,即可以:
Type gcls = typeof("GenericClass<>");
Type nestedCls = gcls.GetNestedType("NestedGenericClass`1");
同样也可以:
Type nestedCls = typeof(GenericClass<>.NestedGenericClass<>);
这些构建形成的最后的genNestedCls的类型值都是一致的,并且和typeof(GenericClass<int>.NestedGenericClass<double>)全等。
然而以上这些对内嵌泛型方法则不适用,实例化该方法则采用如下的直观的方法:
Type gcls = typeof("GenericClass<>");
Type genGcls = gc.MakeGenericClass(typeof(int));
Type m = genGcls.GetMethod("GenericMethod");
Type gm = m.MakeGenericMethod(typeof(double"));
至此形成gm相当于GenericClass<int>.GenericMethod<double>(double)
2. 以下示例代码覆盖了一部分泛型反射的情况。
class ParClass<T, T2>
{
}
class GenClass<T>
{
public void Method<T2>(ParClass<T, T2> pars)
{
}
}
static void Main(string[] args)
{
Type genClassUnassigned = typeof(GenClass<>);
Type genClassAssigned = genClassUnassigned.MakeGenericType(typeof(int));
MethodInfo[] misClassUnassigned = genClassUnassigned.GetMethods();
MethodInfo[] misClassAssigned = genClassAssigned.GetMethods();
MethodInfo miClassUnassigned = misClassUnassigned[0];
MethodInfo miClassAssigned = misClassAssigned[0];
MethodInfo miClassMethodAssigned = miClassAssigned.MakeGenericMethod(typeof(double));
bool isGMClassUnassigned = miClassUnassigned.IsGenericMethod; // true
bool isGMClassAssigned = miClassAssigned.IsGenericMethod; // true
bool isGMClassMethodAssigned = miClassMethodAssigned.IsGenericMethod; // true
bool containsGPClassUnassigned = miClassUnassigned.ContainsGenericParameters; // true
bool containsGPClassAssigned = miClassAssigned.ContainsGenericParameters; // true
bool containsGPClassMethodAssigned = miClassMethodAssigned.ContainsGenericParameters; // false
Type[] typeGenArgsClassUnassigned = miClassUnassigned.GetGenericArguments();
Type[] typeGenArgsClassAssigned = miClassAssigned.GetGenericArguments();
Type[] typeGenArgsClassMethodAssigned = miClassMethodAssigned.GetGenericArguments();
ParameterInfo[] parsClassUnassigned = miClassUnassigned.GetParameters();
ParameterInfo[] parsClassAssigned = miClassAssigned.GetParameters();
ParameterInfo[] parsClassMethodAssigned = miClassMethodAssigned.GetParameters();
Type[] ptsClassUnassigned = new Type[parsClassUnassigned.Length];
Type[] ptsClassAssigned = new Type[parsClassAssigned.Length];
Type[] ptsClassMethodAssigned = new Type[parsClassMethodAssigned.Length];
for (int i = 0; i < ptsClassUnassigned.Length; i++)
ptsClassUnassigned[i] = parsClassUnassigned[i].ParameterType;
for (int i = 0; i < ptsClassUnassigned.Length; i++)
ptsClassAssigned[i] = parsClassAssigned[i].ParameterType;
for (int i = 0; i < ptsClassUnassigned.Length; i++)
ptsClassMethodAssigned[i] = parsClassMethodAssigned[i].ParameterType;
Type t1 = typeof(ParClass<,>);
Type tt1 = ptsClassUnassigned[0];
Type[] gaT1 = t1.GetGenericArguments();
Type[] gaTt1 = tt1.GetGenericArguments();
Type gtT1 = t1.GetGenericTypeDefinition();
Type gtTt1 = tt1.GetGenericTypeDefinition();
bool eq1 = gtT1 == gtTt1; // true
Type t3 = t1.MakeGenericType(typeof(int), typeof(double));
bool eq3 = ptsClassMethodAssigned[0] == t3; // true
bool eq13 = t3.GetGenericTypeDefinition() == gtT1; // true
Type tt2 = ptsClassAssigned[0];
Type[] gaTt2 = tt2.GetGenericArguments();
bool tt2IsG = tt2.IsGenericParameter; // false
bool gaTt20IsG = gaTt2[0].IsGenericParameter; // false
bool gaTt21IsG = gaTt2[1].IsGenericParameter; // true
}
(未完待续)