假设我有一堆实现接口的类:
public interface IBuilding
{
string WhatAmI();
}
Class house:IBuilding
{
string Ibuilding.WhatAmI(){return "A House";}
}
Class Skyscraper:IBuilding
{
string Ibuilding.WhatAmI(){return "A Skyscraper";}
}
Class Mall:IBuilding
{
string Ibuilding.WhatAmI(){return "A Mall";}
}
然后我想动态选择实例化类的内容:
enum buildingType { house, Skyscraper, Mall };
string someMethodOrAnother()
{
string building= textboxBuildingType.Text;
Ibuilding MyBuildingClass;
buildingType UserSelectedClass = (buildingType) Enum.Parse(typeof(buildingType), building);
if (Enum.IsDefined(typeof(buildingType), UserSelectedClass) )
{
MyBuildingClass = (some code that dynamically creates a class instance);
}
else
{
MyBuildingClass = new house();
}
return MyBuildingClass.WhatAmI;
}
现在我可以在switch语句中执行此操作,但我认为我找到了更优雅的技巧。或者是使用界面错误的整个想法?也许我需要代表呢?
答案 0 :(得分:1)
如果我理解你正在尝试做什么,有几种方法可以解决这个问题,但最终你必须有一些逻辑从可用类型列表中选择一种特定类型。
一些选项(不是详尽的清单):
使用反射检查程序集并确定实现所需接口的类型。
使用依赖注入(如LightInject)为您进行装配检查,并为您提供可以实例化的类型列表。 DI库具有各种功能来控制如何发现类型。这是一个非常灵活的解决方案,工作已经完成。
使用XML文件(或其他文件格式)来描述可以使用的类型。这不是很灵活,但它允许您列出您希望可用的类型,而不管程序集中的内容。 (显然,您不能使不存在的类型可用,但您可以隐藏现有类型而无需重新编译代码。)
最后,您将得到一个实现所需接口的类型列表。使用列表,您必须实现某种逻辑来实际选择一个您将实例化的特定类型 - 此逻辑特定于您的应用程序(可能根据列表框中的列表选择类型等):没有人可以告诉你如何做到这一点。
选择类型后,您只需使用Activator.CreateInstance()
创建所选类型的实例即可。或者,如果您使用LightInject,则可以要求库为您返回特定类型的实例。
答案 1 :(得分:1)
一般情况下,我会使用Dictionary
与Activator.CreateInstance
:
Dictionary<buildingType, Type> typeMap = new Dictionary<buildingType, Type>()
{
{ buildingType.House, typeof(House) }
}
IBuilding building = (IBuilding)Activator.CreateInstance(typeMap[userSelection]);
如果这是WPF,您可以使用转换器直接从视图到视图模型执行此操作。