c# - 在字符串中定义的我的类名的实例列表
问题描述
我正在尝试使用先前在字符串变量中定义的类来实例化一个列表。我什至不知道这是否可能,但我认为是的。
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# 中类型的泛型类型参数不能松散地表达 - 它们需要非常明确,因此当您想要混合泛型和反射时,它总是会有点混乱。
这里的第一项工作是获取 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
(并且必须)仅称为非通用IList
API。如果您需要使用通用方面(List<T>
等) - 您可以在内部进行DoTheThing<T>
。列表本身仍然是List<T>
(正确的)T
,即使仅称为IList
- 所以您不能向其中添加不正确的项目等。
推荐阅读
- matlab - 未将输出参数分配给子功能程序时如何解决
- android - ObjectAnimator,如何移动对象两次?
- spring - 如何分别为多个控制器在多个文件中编写Spring Boot测试用例
- caching - 创建/更新/删除后如何清除 .Net Core 上的响应缓存?
- angular - Angular 6将行转换为多列
- magento - 导入产品未显示在前端页面上
- angular - 未在 POST 响应中设置标头
- reactjs - 我可以在哪里更改 react-admin 标题中的个人资料图片?
- python - 列出对 Pandas 列的理解结果:不可散列类型:'dict'
- c++ - 如何在程序的调试版本和编译版本的相对路径之间“动态”更改?