2

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

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

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 继承的每个类的实例?您可以提供的任何见解将不胜感激。

4

4 回答 4

2

请参阅:检查类是否派生自泛型类

另外:通过反射实现接口这可能正是您想要的)

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

于 2009-07-30T03:38:13.573 回答
1

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

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));
}

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

于 2009-07-30T04:12:26.853 回答
0

您将不得不使用反射。

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());
        }
    }
}
于 2009-07-30T03:39:13.710 回答
0

这是我如何做这样的事情:

    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;
    }
于 2009-07-30T03:45:34.777 回答