我正在使用反射来检查程序集是否有实现特定接口的类型(类)。当我找到这样的类型时,我需要检查该类型以查找标有特定属性的方法和枚举。
我使用以下方法来寻找方法:
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 {...}
}
我找了又找,但一直没能找到通过反射找到枚举的方法。
使用反射,您可以使用
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
部分。