第一部份:知道 泛型类型,但泛型参数需要动态的情况
先看一个简单的例子。
class Class1<T> { public void Test(T t) { Console.WriteLine(t); } }
要利用反射动态创建该类型实例,并调用 Test 方法,我们可以使用如下方法
Type type = typeof(Class1<int>); object o = Activator.CreateInstance(type); type.InvokeMember("Test", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, new object[] { 123 });
若泛型参数是未定的,可采用如下方法:
static void InvokeTest(Type t, params object[] args) { Type type = typeof(Class1<>); type = type.MakeGenericType(t); object o = Activator.CreateInstance(type); type.InvokeMember("Test", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, args); }
另外一种情况就是泛型方法,
class Class1 { public void Test<T>(T t) { Console.WriteLine(t); } }
方法类似,只不过这回使用的是 MethodInfo.MakeGenericMethod()
static void InvokeTest(Type t, params object[] args) { Type type = typeof(Class1); object o = Activator.CreateInstance(type); MethodInfo method = type.GetMethod("Test", BindingFlags.Instance | BindingFlags.Public); method = method.MakeGenericMethod(t); method.Invoke(o, args); }
当然还有实例化一个泛型
例如有GenericType<M,N>
Type genericType = typeof(GenericType<>); Type[] templateTypeSet = new[] { typeof(string), typeof(int) }; Type implementType = genericType.MakeGenericType( templateTypeSet )
这样 implementType类型就是赋予了string,int的泛型类了
第二种部份:泛型类型及参数均需要动态指定的情况
Type entityType = typeof(T); Assembly assy = Assembly.GetExecutingAssembly(); //注意:以下字符串中的`1表示泛型参数占位符个数,一个泛型参数则表示为:`1,多个泛型参数则表示为:`N; string genericTypeAssyName = string.Format("{0}.{1}Repository`1", assy.GetName().Name,entityType.Name); var repositoryType = assy.GetType(repositoryAssyName, true, true);//获取泛型类型,不含泛型参数 var repositoryType = repositoryType.MakeGenericType(entityType); //获取泛型类型,并指定泛型参数