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

Lor*_*tel 5 c# reflection

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

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

编辑:

接口不是我想要的方式.

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

jru*_*ell 11

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

然后,您可以使用反射来查找实现该接口的程序集中的所有类型.

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

根据评论更新:

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

interface ISelfTester
{
    void SelfTest();
}

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

    public void SelfTest() 
    {
        // test code
    }

    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样调用每种类型的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();
}
Run Code Online (Sandbox Code Playgroud)


Dat*_*han 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
    }
}
Run Code Online (Sandbox Code Playgroud)

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