首页 > 解决方案 > 在字符串中定义的我的类名的实例列表

问题描述

我正在尝试使用先前在字符串变量中定义的类来实例化一个列表。我什至不知道这是否可能,但我认为是的。

string class1 = "class1";
string class2 = "class2";
bool condition = getCondition();

string classToInstanciate = "";
if(condition) classToInstanciate = class1;
else classToInstanciate = class2;

List<classToInstanciate> dtos = Parse(source).ToList();

这是 pb,显然这不起作用,但我想用需要使用的类来实例化这个列表。

标签: c#stringlist

解决方案


C# 中类型的泛型类型参数不能松散地表达 - 它们需要非常明确,因此当您想要混合泛型和反射时,它总是会有点混乱。

这里的第一项工作是获取 aType而不是 a string。如果您可以typeof始终使用,那会简单得多,即

Type classToInstanciate;
if (condition) classToInstanciate = typeof(Class1);
else classToInstanciate = typeof(Class2);

否则你将不得不使用Type.GetType(fullyQualifiedName)or someAssembly.GetType(fullName)etc,这会变得混乱。

接下来,您需要从反射 ( Type) 切换到泛型 ( <T>)。有多种方法可以做到这一点,但最简单的通常是:MakeGenericMethod. 例如:

class SomeType {
    // can make this non-public, but then you need to specify BindingFlags
    // in the GetMethod call
    public static List<T> DoTheThing<T>(whateverArgs) {
        List<T> dtos = Parse<T>(source).ToList(); // whatever...
        ///
        return dtos;
    }
    ...
    private static IList CallTheThing(Type type, whateverArgs)
    {
        return (IList) typeof(SomeType).GetMethod(nameof(DoTheThing))
              .MakeGenericMethod(type).Invoke(null, whateverArgs);
        // "null" above is the target instance; in this case static, hence null
    }
    // ...
}

然后你可以使用:

IList list = CallTheThing(classToInstanciate, otherArgs);

调用站点处的list(并且必须)仅称为非通用IListAPI。如果您需要使用通用方面(List<T>等) - 您可以在内部进行DoTheThing<T>列表本身仍然是List<T>(正确的)T,即使仅称为IList- 所以您不能向其中添加不正确的项目等。


推荐阅读