如何通过反射为C#泛型类实例传递构造函数参数?
在C#中通过反射创建带参数的泛型类实例
嘿,这个问题我熟!你当前的代码会抛出MissingMethodException,因为你的MyClass<A,B>只有一个带两个参数的构造函数,而你调用的Activator.CreateInstance(typ)是在尝试找无参构造函数,自然找不到啦。下面给你一步步解决的方案:
1. 已知泛型类型参数时,直接传递构造参数
如果你已经明确要创建MyClass<int, int>这种具体类型的实例,只需要给Activator.CreateInstance加上构造函数对应的参数即可:
public class MyClass <A, B> { protected A a; protected B b; public MyClass(A a, B b) { this.a = a; this.b = b; } } static void Main(string[] args) { Type typ = typeof(MyClass<int, int>); // 第二个及以后的参数就是构造函数需要的A和B类型的值 object obj = Activator.CreateInstance(typ, 10, 20); }
这样创建出来的obj内部的a和b就会被初始化为10和20了。
2. 动态指定泛型类型参数时的处理
如果你的泛型类型参数是动态确定的(比如从配置或其他地方获取),需要先从泛型定义生成具体的类型,再传递构造参数:
static void Main(string[] args) { // 先获取泛型类的"模板"(不带具体类型参数的版本) Type genericTemplate = typeof(MyClass<,>); // 用MakeGenericType生成具体的泛型类型,比如这里指定A为string,B为DateTime Type specificType = genericTemplate.MakeGenericType(typeof(string), typeof(DateTime)); // 传递对应类型的构造参数 object obj = Activator.CreateInstance(specificType, "测试文本", DateTime.Now); }
3. 手动操作字段(如果需要额外修改的话)
虽然你的构造函数已经初始化了a和b,但如果后续需要修改这些protected字段,可以通过反射的FieldInfo来操作:
// 假设已经创建了obj实例 Type targetType = obj.GetType(); // 获取protected的a字段,需要指定BindingFlags FieldInfo fieldA = targetType.GetField("a", BindingFlags.Instance | BindingFlags.NonPublic); // 修改字段值 fieldA.SetValue(obj, "新的A值"); // 同理处理b字段 FieldInfo fieldB = targetType.GetField("b", BindingFlags.Instance | BindingFlags.NonPublic); fieldB.SetValue(obj, DateTime.Now.AddDays(1));
关键要点总结
Activator.CreateInstance有多个重载,带参数的版本会自动匹配对应签名的构造函数;- 动态生成泛型类型必须用
MakeGenericType方法,传入具体的类型参数; - 访问非public的成员(比如protected字段)时,必须指定正确的
BindingFlags,否则反射会找不到目标成员。
内容的提问来源于stack exchange,提问作者alqueen
相关产品推荐
相关产品推荐

