C#利用反射动态创建泛型实例
本文详细介绍了如何在C#中利用System.Reflection.Assembly的CreateInstance方法,通过反射动态构建带有多个类型参数的泛型类实例。该方法通过特定的字符串格式定义泛型形参与实参的映射关系,解决了运行时根据字符串信息生成复杂泛型对象的需求。
实现原理与核心逻辑
在C#中,泛型类型需要通过具体的类型参数进行实例化。当我们需要在不编译时确定的情况下创建泛型实例时,通常采用反射技术。`System.Reflection.Assembly.CreateInstance(string)`方法允许我们通过指定完整的类型名称来创建对象,而对于泛型类型,必须按照特定的格式提供类型参数。
假设我们有一个名为 `Demo.GenericsSimple<T,TT>` 的泛型类,其中 `T` 和 `TT` 是泛型参数。若要通过反射创建一个其实例(例如 `GenericsSimple<string, int>`),关键在于正确构建那个包含泛型定义的字符串标识符。
操作步骤:代码实现
第1步:准备泛型类原型
首先,我们需要一个目标泛型类。为了演示,我们定义一个简单的泛型结构体,并对类型参数施加约束:
namespace Demo
{
// 定义泛型类,T必须是引用类型,TT必须是值类型
public class GenericsSimple<T, TT> where T : class where TT : struct
{
// 类主体为空,仅用于测试反射创建
}
}
第2步:构建反射创建的字符串路径
使用 `Assembly.GetExecutingAssembly().CreateInstance()` 方法创建实例时,第一个参数是类型的完整限定名。对于泛型,格式如下:
- 类型基础名:命名空间.类名后跟反引号及形参数量(例如 `Demo.GenericsSimple`2`)。
- 实际类型参数:紧跟在反引号后,用双中括号
[[...]]包裹。内部格式为:全名类型, 程序集名称。如果有多个类型参数,它们之间用逗号分隔。
针对上述类的具体调用代码如下:
using System;
using System.Reflection;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
// 尝试通过反射创建 Demo.GenericsSimple<string, int>
// "mscorlib" 是包含 System.String 和 System.Int32 的旧版.NET程序集名称
string typeName = "Demo.GenericsSimple`2[[System.String, mscorlib],[System.Int32, mscorlib]]";
var instance = Assembly.GetExecutingAssembly().CreateInstance(typeName);
if (instance == null)
{
Console.WriteLine("实例创建失败:返回null");
}
else
{
Console.WriteLine($"成功创建实例!类型全名: {instance.GetType().FullName}");
}
Console.WriteLine("===end===");
Console.Read();
}
}
}
关键点解析
- 反引号与数量:
`2表示该泛型类有两个类型参数。如果只有单泛型(如 List<T>),则应写为`1。 - 程序集名称匹配:
[System.String, mscorlib]中的mscorlib是关键。必须填写定义该非泛型类型所在的程序集名称。在现代.NET Core/.NET 5+环境中,核心类型可能位于System.Private.CoreLib或其他位置,需根据实际项目环境调整,否则会导致CreateInstance返回null。 - 空返回值处理:如果类型不存在、泛型定义错误或类型参数不符合where约束,此方法会静默返回
null,因此代码中必须进行空值检查。
以上就是C#通过反射创建自定义泛型实例的详细内容,更多关于C#反射机制与高级用法的相关资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













