C# 通过反射执行泛型类的方法
有个需求需要实现根据参数中指定类型,反序列化一个 JSON 字符串,然后将反序列化后的结果传到一个泛型类的方法。
示例用类:
csharp
namespace N {
class A {
}
class B<T> {
public M(T t) {
}
}
}
需要实现的方法:
csharp
void V (string typeName, string jsonData) {
}
如果采用如下方法调用(GetType 方法见文章后面的 附 1)
csharp
void V (string typeName, string jsonData) {
var typeA = GetType(typeName);
var b = new B<typeA>();
}
则会报错:
“typeA”是 变量,但此处被当做 类型 来使用
应使用 MakeGenericType
方法来创建泛型类的类型,之后再通过 Activator.CreateInstance
方法创建实例(参考 这篇博客),示例如下:
csharp
void V (string typeName, string jsonData) {
// 反序列化 json 为指定类型
var typeA = GetType(typeName);
var data = JsonConvert.DeserializeObject(jsonData, typeA);
// 创建泛型类的类型
var typeB = typeof(B<>).MakeGenericType(typeA);
// 创建泛型类的实例
object objB = Activator.CreateInstance(typeB);
// 获取泛型类的方法并调用
MethodInfo method = typeB.GetMethod("M", BindingFlags.Instance | BindingFlags.Public);
method.Invoke(objB, new object[] { data });
}
附 1. GetType
方法如下(参考自 这篇博客):
csharp
/// <summary>
/// 根据字符串获取 Type
/// </summary>
/// <param name="typeName"></param>
/// <returns></returns>
private Type GetType(string typeName)
{
Type type = null;
Assembly[] assemblyArray = AppDomain.CurrentDomain.GetAssemblies();
int assemblyArrayLength = assemblyArray.Length;
for (int i = 0; i < assemblyArrayLength; ++i)
{
type = assemblyArray[i].GetType(typeName);
if (type != null)
{
return type;
}
}
return type;
}