我正在使用LINQ-to-XML来查询文件以获取对象列表。它们都具有相同的结构(一组选项,一组不确定长度的参数)。基于XML文件中的名称,我想将参数用于完全不同的东西 - 所以我创建了这个对象的子类。
我的问题是 - 如何动态调用正确的构造函数,而不执行类似case语句的操作?或者从XML优雅地实例化不同子类的解决方案是否位于其他地方?
class Object1
{
string name;
OptionObj opt;
List<Param> parameters;
}
class sonOfObject : Object1
{
public void ExecuteSomething()
{
//do something with the parameters
}
}
class secondSonOfObject : Object1
{
public void ExecuteSomething()
{
//do something entirely different with the parameters
}
}
var query = from x in xmlDoc.Descendants("Object")
select new Object
{
//select the object from the XML
}
在这段代码之后,我可以使用复制构造函数从更通用的查询对象生成一个sonOfObject。但是,如何根据子类的名称动态地执行此操作?
我知道您可以从类型中获取MethodInfo并调用它ala ...
MethodInfo m = t.GetMethod(someName);
m.Invoke(yourObj, null);
但这意味着我必须实例化这些子类对象中的9个或10个(并为每个子类获取它们的类型),并且仍然以某种case语句结束。
是否有更优雅的方式来动态调用子类构造函数?
答案 0 :(得分:7)
Activator.CreateInstance允许您将类名作为字符串传递,它将返回该类的新实例。
答案 1 :(得分:3)
为了让一个类参与这个方案,我会用一个自定义属性来标记它,它给它一个“XML名称”。
然后使用反射查找标有该属性的所有Type
并将其放入Dictionary<string, Type>
。此时,您需要决定如何查找可能为系统提供类型的其他程序集。一种简单的方法是在同一目录中查找扩展名为.DLL的其他文件。
然后,只要您要使用XML创建相应Type
的实例的字符串,只需按名称查看Type
中的Dictionary
并调用{ {1}}和Type.GetConstructor
。
这样做的好处是XML中的标识符与代码的物理布局是分开的 - 您可以在程序集中移动类型或重命名它们而不会使旧的XML文件失效。