I am using reflection to inspect an assembly for types (classes) that implement a certain interface. When I find such a type, I then need to inspect the type to find methods and enums marked with a particular attribute.
I use the following to find methods:
foreach (MemberInfo member in types[index].FindMembers(MemberTypes.Method,
BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance,
new MemberFilter(WorkflowMethodFilter), ""))
WorkflowMethodFilter checks the MemberInfo for the presence of the custom attribute.
That works great for e.g.
[MyCustomAttr]
public void Method1() {...}
But static methods are not found in the call to FindMembers. That is, WorkflowMethodFilter is never called for static methods.
[MyCustomAttr]
public static void Method2() {...}
Is there a way to find static methods?
Any idea how I go about finding enums that are defined within the class?
public class Foo : IMyCustomInterface
{
[MyCustomAttr]
public enum MyEnum {...}
}
I have looked and looked, but haven't been able to find a way to find the enum through reflection.
Using Reflection you can easily retrieve properties and methods using GetMethods
and GetProperties
methods and filter on attribute implementation.
For fields, use GetFields
.
For nested types, like your enum
, you should use GetNestedTypes
.
Here is an example:
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(typeof(MyCustomAttribute), true).Length > 0) // 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($"Property 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($"Field with name \"{field.DeclaringType?.FullName ?? "NoDeclaringType"}.{field.Name}\" found implementing attribute");
var nestedTypesImplementingAttribute = classType.GetNestedTypes()
.Where(e => e.GetCustomAttribute<MyCustomAttribute>(false) != null)
.ToList();
foreach (Type nestedType in nestedTypesImplementingAttribute)
Console.WriteLine($"Nested type with name \"{nestedType.DeclaringType?.FullName ?? "NoDeclaringType"}.{nestedType.Name}\" found implementing attribute");
public class MyClass : BaseClass
{
[MyCustom]
int _attributeField = 0;
int _attributelessField = 0;
[MyCustom]
public AttributeEnum AttributeProperty { get; set; }
public int AttributeLessProperty { get; set; }
[MyCustom]
public void AttributeMethod() { }
public override void AttributeMethodInherit() { }
public void AttributelessMethod() { }
[MyCustom]
public enum AttributeEnum
{
}
public enum AttributelessEnum
{
}
}
public class BaseClass
{
[MyCustom] //This is for the inherit example
public virtual void AttributeMethodInherit() { }
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Enum)]
public class MyCustomAttribute : Attribute { }
Output:
Working with "MyClass"
Method with name "MyClass.AttributeMethod" found implementing attribute
Method with name "MyClass.AttributeMethodInherit" found implementing attribute
Property with name "MyClass.AttributeProperty" found implementing attribute
Field with name "MyClass._attributeField" found implementing attribute
Nested type with name "MyClass.AttributeEnum" found implementing attribute
Additionally, ensure your defined attributes ends with Attribute
and not Attr
, this is more standard and makes code predictable. This also allows you to omit the Attribute
part when implementing the attribute.