我可以在运行时动态实例化接口吗?是的,我可以,但有更好的方法吗

本文关键字:我可以 更好 方法 运行时 动态 实例化 接口 是的 | 更新日期: 2023-09-27 18:29:41

假设我有一堆实现接口的类:

    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语句中执行此操作,但我认为我找到了一种更优雅的技术。或者使用接口的整个想法是错误的?也许我需要一个代表?

我可以在运行时动态实例化接口吗?是的,我可以,但有更好的方法吗

通常,我会将DictionaryActivator.CreateInstance:一起使用

Dictionary<buildingType, Type> typeMap = new Dictionary<buildingType, Type>()
{
   { buildingType.House, typeof(House) }
}
IBuilding building = (IBuilding)Activator.CreateInstance(typeMap[userSelection]);

如果这是WPF,则可以使用转换器直接从视图到视图模型执行此操作。

如果我理解你试图正确地做什么,有几种方法可以做到这一点,但最终你必须有一些逻辑,从可用类型列表中选择一个特定的类型。

一些选项(不是详尽的列表):

  • 使用反射检查程序集,并确定实现所需接口的类型。

  • 使用依赖项注入(如LightInject)为您进行程序集检查,并为您提供一个可以实例化的类型列表。DI库具有各种功能来控制如何发现类型。这是一个非常灵活的解决方案,工作是为您完成的。

  • 使用XML文件(或其他文件格式)来描述可以使用的类型。这不是很灵活,但它允许您列出希望可用的类型,而不管程序集中有什么。(显然,您不能使不存在的类型可用,但您可以在不重新编译代码的情况下隐藏现有类型。)

最后,您将得到一个实现所需接口的类型列表。有了列表,你必须实现某种逻辑来实际选择一个要实例化的特定类型——这种逻辑是特定于你的应用程序的(可能是根据列表框中的列表来选择类型,等等):没有人能告诉你如何做到这一点。

选择类型后,只需使用Activator.CreateInstance()即可创建所选类型的实例。或者,如果您使用LightInject,您可以要求库为您返回特定类型的实例。

相关文章: