【问题标题】:Is it possible to get an instance of every class that inherits from an interface?是否可以获得从接口继承的每个类的实例?
【发布时间】:2010-11-15 07:35:06
【问题描述】:

我正在做一个小项目,我试图弄清楚是否有可能获得从特定接口继承的每个类的实例。

这是我想要完成的一个简化示例:

public interface IExample
{
    string Foo();
}

public class Example1 : IExample
{
    public string Foo()
    {
        return "I came from Example1 !";
    }
}

public class Example2 : IExample
{
    public string Foo()
    {
        return "I came from Example2 !";
    }
}

//Many more ExampleN's go here

public class ExampleProgram
{

    public static void Main(string[] args)
    {
        var examples = GetExamples();

        foreach (var example in examples)
        {
            Console.WriteLine(example.Foo());
        }
    }

    public static List<IExample> GetExamples()
    {
        //What goes here?
    }
}

GetExamples 方法是否有任何方法(没有硬编码)来返回一个列表,该列表包含从接口 IExample 继承的每个类的实例?非常感谢您提供的任何见解。

【问题讨论】:

    标签: c# inheritance instance


    【解决方案1】:

    见:Check if a class is derived from a generic class

    另外:Implementations of interface through Reflection这可能正是您想要的

    您基本上只需要枚举目标程序集中的每个类型并测试它是否实现了接口。

    【讨论】:

    • 第二个链接回答了您的问题,但它(显然)只知道您已加载的程序集类型。因此,如果您正在创建一个库类型类,您可能不知道实现您的接口的所有内容。
    • 第二个链接是我在寻找实现该接口的类型方面所寻找的。下面马特凯洛格回答的后半部分演示了如何创建对象。我希望我可以将两个答案都标记为正确:P 感谢您的帮助!
    【解决方案2】:

    基于马特的解决方案,我会像这样实现它:

    public static List<IExample> GetExamples()
    {
        return GetInstances<IExample>().ToList();
    }
    
    private static IEnumerable<T> GetInstances<T>()
    {
        return Assembly.GetExecutingAssembly().GetTypes()
            .Where(type => type.IsClass &&
                           !type.IsAbstract &&
                           type.GetConstructor(Type.EmptyTypes) != null &&
                           typeof (T).IsAssignableFrom(type))
            .Select(type => (T) Activator.CreateInstance(type));
    }
    

    此解决方案跳过无法实例化的类型,例如抽象类、派生接口和没有默认(无参数)公共构造函数的类。

    【讨论】:

      【解决方案3】:

      我会这样做:

          public static List<IExample> GetExamples()
          {
              var assembly = Assembly.GetExecutingAssembly();
              var types = assembly.GetTypes().Where(t => t.GetInterfaces().Any(i => i == typeof(IExample))).ToList();
      
              List<IExample> returnMe = new List<IExample>();
              foreach (var type in types)
                  returnMe.Add((IExample) Activator.CreateInstance(type));
      
              return returnMe;
          }
      

      【讨论】:

      • routeNpingme 首先回应了如何获取从给定接口继承的类型,但您演示了如何返回这些类型的具体实例。我希望我可以将两个答案都标记为正确:P 感谢您的帮助!
      【解决方案4】:

      你必须使用反射。

      Assembly.GetExecutingAssembly 应该是您的起点。

      编辑:应该有帮助的代码

      Type[] types = Assembly.GetExecutingAssembly().GetTypes();
      foreach(Type tp in types)
      {
          if (typeof(IExample).IsAssignableFrom(tp))
          {
              if (tp.IsInterface == false)
              {
                  IExample t = Activator.CreateInstance(tp) as IExample;
                  Console.WriteLine(t.Foo());
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-12-23
        • 1970-01-01
        • 1970-01-01
        • 2013-02-24
        • 2020-11-14
        • 1970-01-01
        • 1970-01-01
        • 2018-05-28
        • 1970-01-01
        相关资源
        最近更新 更多