在C#中查找包含方法的所有类

时间:2010-05-05 19:02:11

标签: c# reflection

我想在命名空间中搜索包含某个方法的所有类。如果一个类包含一个方法,那么我想创建一个类的实例并运行该方法。

显然我必须从反思开始,但​​我仍然坚持要去哪里。

编辑:

接口不是我想要的方式。

我正在寻找的是将测试功能嵌入到代码中,但是只有一个调用接口。如果有自检功能,请调用它。如果没有,请忽略它。

3 个答案:

答案 0 :(得分:11)

创建一个声明方法的接口,然后让各种类实现该接口。

然后,您可以将反射用于find all types within an assembly that implement that interface

从那里你需要创建每种类型的实例,然后调用该方法。实施细节将根据您的尝试而有所不同。

根据评论进行更新:

我仍然认为接口(或属性)是要走的路。这就是它如何与界面一起使用。

interface ISelfTester
{
    void SelfTest();
}

class SomeClass : ISelfTester
{
    /* ... */

    public void SelfTest() 
    {
        // test code
    }

    /* ... */
}

然后你可以像这样调用每种类型的SelfTest方法(借用Dathan和Darren Kopp):

var type = typeof(ISelfTester);
var types = AppDomain.CurrentDomain.GetAssemblies()
    .Select(x => x.GetTypes())
    .SelectMany(x => x)
    .Where(x => x.Namespace == "My.Name.Space" && type.IsAssignableFrom(x));

foreach (Type t in types)
{
    ISelfTester obj = Activator.CreateInstance(t) as ISelfTester;
    obj.SelfTest();
}

答案 1 :(得分:11)

如果没有关于区分方法的更多信息,我只是假设它的名称是区分的,而且是公开的。名称假设是危险的,所以我不建议这样做,但以下应该做你想要的(假设Activator能够创建一个实例)。

编辑:添加Where(x => x.Namespace == "My.Name.Space")以将结果限制为单个目标命名空间。

编辑:添加了if ... else来处理静态方法。

var methods = AppDomain.CurrentDomain.GetAssemblies()
    .Select(x => x.GetTypes())
    .SelectMany(x => x)
    .Where(x => x.Namespace == "My.Name.Space")
    .Where(c => c.GetMethod("MethodName") != null)
    .Select(c => c.GetMethod("MethodName"));

foreach (MethodInfo mi in methods)
{
    if (mi.IsStatic)
    {
        mi.Invoke(null, null); // replace null with the appropriate arguments
    }
    else if (!mi.DeclaringType.IsAbstract)
    {
        var obj = Activator.CreateInstance(mi.DeclaringType);
        mi.Invoke(obj, null); // replace null with the appropriate arguments
    }
}

如果您可以控制类型,那么jrummel关于接口的建议是一种更安全的方法。

答案 2 :(得分:2)

如上所述,一种选择是使用Reflection,但不是按名称查找方法,而是查找使用适当的自定义属性标记的方法。这类似于MS DataContractSerializer对[OnDeserializing]等属性的处理方式。通过这种方式,类实现者特意拼出了他们对该方法的意图,而不是由于它具有特定的名称而突然发生意外的事情。

另一方面,由于你所追求的是一种测试方法,你可以查看NUnit之类的内容。有几个优秀的免费单元测试框架。它们还提供了可以帮助您进行测试的其他功能,因为它们为您可能想要的不同类型的测试断言提供了脚手架。