c# - 如何使用字符串作为泛型类型
问题描述
我有以下代码。
string name = GetClassName();
switch (name)
{
case "Class1":
new Generic<Class1>().DoSomething();
break;
case "Class2":
new Generic<Class2>().DoSomething();
break;
case "Class3":
new Generic<Class3>().DoSomething();
break;
default:
break;
}
name 的值可能超过 50 个,并且有超过 50 个 case 似乎是不明智的。我认为必须有一些通用的方法来做到这一点。
喜欢
string name = GetClassName();
new Generic<ConverToClass(name)>().DoSomething();
让我把我的问题说清楚。感谢您的回复。
实际上,这段代码只是我项目的一个片段,它是用 .NET 5.0 编写的。
我有一个用于 CRUD 实体的通用类 EntityDao,例如 Create、Update、Remove,EntityType 可能是 User、Setting 等。还有一个 GRPC 服务,它接受客户端请求,包括作为字符串的实体类型、到 CRUD 实体的实体数据。
class Request {
string Type; // Entity type, which is the string of EntityType, like "User", "Setting".
EntityAction Action; //Create, Update, Remove and etc.
ByteString Data; // Holding entity serialized data.
}
还有一种方法可以处理来自客户端的请求。
Request request = GetClientRequst()
//container is IContainer of Autofac.
switch (request.Type) {
case "User":
container.Reslove<EntityDao<User>>().Create(request.Data); // Assuming Action is Create
break;
case "Setting":
container.Reslove<EntityDao<Setting>>().Create(request.Data); // Assuming Action is Create
break;
case "Other": // Have more than 50 entity types.
break;
}
解决方案
string name = GetClassName();
Type klass = Type.GetType("Namespace." + name); // Replace "Namespace." with all the namespaces the classes live in, as the argument to `Type.GetType()` should be a fully-qualified name
if (klass is null)
{
// Class was not found
}
当然,您还需要创建一个实例Generic<klass>
:
Type genericOfKlass = typeof(Generic<>).MakeGenericType(klass);
然后实例化它:
object instance = Activator.CreateInstance(genericOfKlass);
然后调用.DoSomething()
它:
MethodInfo doSomething = genericOfKlass.GetMethod("DoSomething", BindingFlags.Public | BindingFlags.Instance);
doSomething.Invoke(instance, new object[] { });
如您所见,反射(这种动态编程称为反射)并不容易,但在 .NET 中是可能的。
编辑:带有请求数据的完整示例:
Request request = GetClientRequst();
//container is IContainer of Autofac.
Type requestType = Type.GetType("Namespace." + requestType); // Replace "Namespace." with all the namespaces the classes live in, as the argument to `Type.GetType()` should be a fully-qualified name
Type entityDao = typeof(EntityDao<>).MakeGenericType(requestType);
MethodInfo containerResolve = container.GetType().GetMethod("Resolve");
MethodInfo genericContainerResolve = containerResolve.MakeGenericMethod(entityDao);
object resolveResult = genericContainerResolve.Invoke(container, new object[] { });
MethodInfo create = resolveResult.GetType().GetMethod("Create");
create.Invoke(resolveResult, new object[] { request.Data });
推荐阅读
- node.js - Hapi 未知认证策略 jwt
- c# - C# 构造函数由于另一个构造函数而中断
- java - 读取包含无符号数的二进制流
- python - Airflow - 为 DockerOperator 获取并清理 run_id
- pycharm - 如何为 pycharm 和 spyder 设置站点包目录?
- python - 如何从下一个名称中减去存储在 python 列表中的列名?
- vba - 在 Access CSV 导出顶部附加其他行
- javascript - 多个地址自动完成字段?(#Google Places API & getElementById #)
- deep-learning - 如何在 Pytorch 中分别连接两个大小为 [B,C,13,18] 和 [B,C,14,18] 的张量?
- java - 如何模拟任务:Spring中的执行者