You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过反射为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:07:51