如何通过反射查找类中定义的公共枚举和公共静态方法

问题描述 投票:0回答:1

我正在使用反射来检查程序集是否有实现特定接口的类型(类)。当我找到这样的类型时,我需要检查该类型以查找标有特定属性的方法和枚举。

我使用以下方法来寻找方法:

foreach (MemberInfo member in types[index].FindMembers(MemberTypes.Method,
                                                   BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance,
                                                   new MemberFilter(WorkflowMethodFilter), ""))

WorkflowMethodFilter 检查 MemberInfo 是否存在自定义属性。

这对于例如

非常有用
[MyCustomAttr]
public void Method1() {...}

但是在FindMembers的调用中找不到静态方法。也就是说,静态方法永远不会调用 WorkflowMethodFilter。

[MyCustomAttr]
public static void Method2() {...}

有没有办法找到静态方法?

知道如何查找类中定义的枚举吗?

public class Foo : IMyCustomInterface
{
     [MyCustomAttr]
     public enum MyEnum {...}
}

我找了又找,但一直没能找到通过反射找到枚举的方法。

c# reflection
1个回答
0
投票

使用反射,您可以使用

GetMethods
GetProperties
方法轻松检索属性和方法,并过滤属性实现。

也可以对字段使用相同的方法,请改用

GetFields

这是一个例子:

using System;
using System.Linq;
using System.Reflection;

Type classType = typeof(MyClass);

Console.WriteLine($"Working with \"{classType.Name}\"");

var methodsImplementingAttribute = classType.GetMethods()
    .Where(m => m.GetCustomAttributes<MyCustomAttribute>(true) != null) // Set inherit to true if it should check ancestors
    .ToList();

foreach (MethodInfo method in methodsImplementingAttribute)
    Console.WriteLine($"Method with name \"{method.DeclaringType?.FullName ?? "NoDeclaringType"}.{method.Name}\" found implementing attribute");

var propertiesImplementingAttribute = classType.GetProperties()
    .Where(p => p.GetCustomAttributes(typeof(MyCustomAttribute), false).Length > 0) //using GetCustomAttributes all defined attributes of Type
    .ToList();

foreach (PropertyInfo property in propertiesImplementingAttribute)
    Console.WriteLine($"Method with name \"{property.DeclaringType?.FullName ?? "NoDeclaringType"}.{property.Name}\" found implementing attribute");


var fieldsImplementingAttribute = classType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance) //These binding flags are here because the fields are private
    .Where(f => f.GetCustomAttribute<MyCustomAttribute>(false) != null) //using GetCustomAttribute<T> returns a single attribute
    .ToList();

foreach (FieldInfo field in fieldsImplementingAttribute)
    Console.WriteLine($"Method with name \"{field.DeclaringType?.FullName ?? "NoDeclaringType"}.{field.Name}\" found implementing attribute");

public class MyClass : BaseClass
{
    [MyCustom]
    int _attributeField = 0;

    int _attributelessField = 0;

    [MyCustom]
    public MyEnum AttributeProperty { get; set; }

    public int AttributeLessProperty { get; set; }

    [MyCustom]
    public void AttributeMethod() { }

    public override void AttributeMethodInherit() { }

    public void AttributelessMethod() { }
}

public class BaseClass
{
    [MyCustom] //This is for the inherit example
    public virtual void AttributeMethodInherit() { }
}

public enum MyEnum
{

}

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field)]
public class MyCustomAttribute : Attribute { }

此外,确保您定义的属性以

Attribute
结尾,而不是
Attr
,这更加标准,并使代码可预测。这还允许您在实现属性时省略
Attribute
部分。

© www.soinside.com 2019 - 2024. All rights reserved.