简体   繁体   English

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

[英]Finding all classes containing a method in C#

I want to search through all classes in a namespace for those containing a certain method. 我想在命名空间中搜索包含某个方法的所有类。 If a class contains a method then I want to create an instance of the class and run the method. 如果一个类包含一个方法,那么我想创建一个类的实例并运行该方法。

Obviously I have to start with reflection but I'm stuck on where to go. 显然我必须从反思开始,但​​我仍然坚持要去哪里。

Edit: 编辑:

Interfaces are not the way I want to do this. 接口不是我想要的方式。

What I'm looking for is embedding testing functions into the code but a single calling interface. 我正在寻找的是将测试功能嵌入到代码中,但是只有一个调用接口。 If there's a self-test function, call it. 如果有自检功能,请调用它。 If there isn't, ignore it. 如果没有,请忽略它。

Create an interface that declares the method and then have various classes implement that interface. 创建一个声明方法的接口,然后让各种类实现该接口。

You can then use reflection to find all types within an assembly that implement that interface . 然后,您可以使用反射来查找实现该接口的程序集中的所有类型

From there you'll need to create an instance of each type and then call the method. 从那里你需要创建每种类型的实例,然后调用该方法。 The implementation details will vary depending on what you are trying to do. 实施细节将根据您的尝试而有所不同。

Update based on comments: 根据评论更新:

I still think an interface (or attribute) is the way to go. 我仍然认为接口(或属性)是要走的路。 This is how it would work with an interface. 这是它如何与界面一起使用。

interface ISelfTester
{
    void SelfTest();
}

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

    public void SelfTest() 
    {
        // test code
    }

    /* ... */
}

You could then invoke each type's SelfTest method like so (borrowing from Dathan and Darren Kopp): 然后,您可以像这样调用每种类型的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();
}

Without more information about what distinguishes the method, I'm just going to assume it's distinguished by name, and it's public. 如果没有关于该方法的区别的更多信息,我只是假设它的名称有所区别,而且它是公开的。 The name assumption is dangerous, so I wouldn't recommend doing this, but the following should do what you want (assuming Activator is able to create an instance). 名称假设是危险的,所以我不建议这样做,但以下应该做你想要的(假设Activator能够创建一个实例)。

EDIT : Added Where(x => x.Namespace == "My.Name.Space") to limit the results to a single target namespace. 编辑 :添加Where(x => x.Namespace == "My.Name.Space")将结果限制为单个目标命名空间。

EDIT : Added if ... else to handle the case of static methods. 编辑 :添加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
    }
}

If you have control over the types, though, jrummel's suggestion about interfaces is a much safer way to do this. 但是,如果您可以控制类型,那么jrummel关于接口的建议是一种更安全的方法。

One option would be to use Reflection, as described above, but rather than finding the method by name, look for a method tagged with an appropriate custom attribute. 一种选择是使用Reflection,如上所述,但不是按名称查找方法,而是查找使用适当的自定义属性标记的方法。 This is similar to what the MS DataContractSerializer does with attributes like [OnDeserializing] . 这类似于MS DataContractSerializer对[OnDeserializing]等属性的处理方式。 This way the class implementer is specifically spelling out their intent for the method, rather than having it suddenly do something unexpected as a result of it having a particular name. 通过这种方式,类实现者专门拼出他们对该方法的意图,而不是由于它具有特定名称而突然发生意外事件。

On a side note, since what you're after is a test method, you might check out something like NUnit . 另外,由于你所追求的是一种测试方法,你可能会看看像NUnit这样的东西。 There are several excellent free unit testing frameworks out there. 有几个优秀的免费单元测试框架。 They also provide additional features that can help with your testing, as they provide the scaffolding for the different types of test assertions you might want to make. 它们还提供了可以帮助您进行测试的其他功能,因为它们为您可能想要的不同类型的测试断言提供了脚手架。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM