动态访问给定命名空间的类

时间:2010-05-23 01:51:30

标签: c# reflection clr

我正在编写一个将由很多类实现的接口,我正在编写一个包含这些实现的实例集合的类。每个类都有一个默认的构造函数。

那么,是否有一种简单的方法(例如使用某种反射)将每个实现类的实例放入集合中?除了手动操作外,这很简单,是的,但是很多工作和容易出错(如果我在编写方法时错过了实现怎么办?如果新的实现出现了,我忘了更新给定的方法?)。

所以,我想要的是能够迭代给定命名空间的所有类,或者可能通过所有可用类的列表。然后,我的方法只需通过反射检查给定的类是否实现了给定的接口,如果确实如此,则将其放入集合中。

谢谢。

2 个答案:

答案 0 :(得分:2)

您需要调用Assembly.GetTypes()来获取程序集中的每个类,调用typeof(IMyInterface).IsAssignableFrom来检查实现该接口的类,然后调用Activator.CreateInstanse来实例化该类。

使用LINQ:

typeof(IMyInterface).Assembly.GetTypes()
                             .Where<Type, bool>(typeof(IMyInterface).IsAssignableFrom)
                             .Select(t => Activator.CreateInstance(typeof(T)))
                             .ToArray()

答案 1 :(得分:2)

这里没有LinQ,散布开来让你可以看到发生了什么。但除此之外,它与SLaks所写的完全相同。

它是所有实现接口IFoo的类。

 List<IFoo> items = new List<IFoo>();

//Iterate through all types
foreach (Type type in Assembly.GetExecutingAssembly.GetTypes) {

    //Check the type is public and not abstract
    if (!type.IsPublic | type.IsAbstract)
        continue;

    //Check if it implements the interface IFoo
    if (typeof(IFoo).IsAssignableFrom(type)) {

        //Create an instance of the class
        //If the constructor has arguments put them after "type" like so: 
        //Activator.CreateInstance(type, arg1, arg2, arg3, etc...)
        IFoo foo = (IFoo)Activator.CreateInstance(type);

        //Add the instance to your collection
        items.Add(foo);

    }
}