首页 > 解决方案 > 如何使用字符串作为泛型类型

问题描述

我有以下代码。

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;
}

标签: c#

解决方案


看看Type.GetType(string)

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 });

推荐阅读