.net - 通过反射从某个命名空间的类调用方法

时间:2010-03-14 16:45:40

标签: c# .net reflection

SPL和PHP允许您从类中动态创建对象,满足某些条件,例如实现某些接口和类似的东西。

但是,我想在c#中做类似的事情并自动从命名空间中的所有类创建对象,并从那些实现特定接口的类中调用特定方法。

我开发桌面应用程序的经验非常有限。我不太确定我是否应该使用委托来存档这个,或者反射是否真的要走了。

3 个答案:

答案 0 :(得分:3)

你必须使用反射 - 你可能使用代表,但它并不完全清楚;这将取决于你正在做什么。

Assembly.GetTypes()将返回程序集中的所有类型;您可以使用Type.IsAssignableFrom()来检查类型是实现接口还是从另一个特定类型派生,Type.Namespace来检查命名空间等。Activator.CreateInstance()将通过调用无参数来创建类型的实例构造函数(如果有的话)或者您可以使用CreateInstance的其他重载调用带有参数的构造函数,或者首先使用Type.GetConstructors()获取它。

如果您已经测试了类型是否实现了接口,那么在构造实例之后,您可以将引用转换为该接口,并在不使用任何反射的情况下调用该接口中的方法。如果您在执行时只知道方法的名称,那么您需要致电Type.GetMethod()以获取MethodInfo,然后Invoke()来调用它。

所有这一切都有点容易出错并且当然很复杂 - 如果你能找到任何保持静态打字的方式,这将使你的生活更轻松。这里的大局是什么?你想要实现什么目标?

答案 1 :(得分:1)

我不确定为什么你想要在类中实例化每个类型的实例,但是你可以使用反射来实现它。此外,对程序集中的每个类型进行实例化比对命名空间中的每个类型进行实例化更容易。无论如何,这里有一个你可能做的样本:

var assembly = Assembly.GetExecutingAssembly(); //here you would retrieve the assembly you wish to search.

foreach ( var type in assembly.GetTypes() )
{
    if ( type.GetInterface( "IMyInterface", true ) != null )
    {
        var instance = Activator.CreateInstance( type ) As IMyInterface;
        instance.MethodIWantToCall();
    }
}

答案 2 :(得分:0)

以下代码将查找实现IDisposable并位于特定名称空间下的所有类型。如果类型是Form,则调用ShowDialog方法。

        Type[] types = System.Reflection.Assembly.GetExecutingAssembly().GetTypes();
        foreach (Type type in types)
        {
            if (type.Namespace.Equals("TestApp") &&
                (type.GetInterface("System.IDisposable") != null))
            {
                object obj = Activator.CreateInstance(type);
                if (obj is Form)
                    ((Form)obj).ShowDialog();
            }
        }