Valtaroth
Valtaroth

Reputation: 65

C# Reflection: GetMethods(..) failing to retrieve anything

I am currently trying to get a very specific set of methods but am failing to do so. I need to get all methods that match a certain signature from all classes that implement a certain interface.

What I've got so far is:

IEnumerable<System.Type> classes = Assembly.GetAssembly(typeof(IActionMethod)).GetTypes().Where(x => x.GetInterface("IActionMethod") != null);
MethodInfo[] methods;
List<MethodInfo> relevant;
ParameterInfo[] parameters;
foreach(System.Type cls in classes)
{
    methods = cls.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public);
    relevant.Clear();
    for(int i = 0; i < methods.Length; i++)
    {
        parameters = methods[i].GetParameters();
        if(parameters.Length == 1 && parameters[0].GetType() == typeof(GameObject) && methods[i].ReturnType == typeof(void))
            relevant.Add(methods[i]);
    }
}

This code already fails at GetMethods(..)which is not returning any methods. What I do not understand is, that I am able to receive all public methods of any of the relevant classes if they do not implement the interface.

The interface itself does not contain anything, I am only using it to "mark" the relevant classes, as I could not come up with any other solution to do so.

Can anyone tell me why the interface is rendering GetMethodsuseless or point me to the error in my code above?

Upvotes: 3

Views: 573

Answers (3)

Wai Ha Lee
Wai Ha Lee

Reputation: 8805

As an aside, Microsoft recommends not using 'marker interfaces' and instead suggests using attributes. You can then use Memberinfo.IsDefined() instead of checking for the interface.

Upvotes: 3

Konrad Kokosa
Konrad Kokosa

Reputation: 16878

To find all classes that implements specific interface, you should use rather IsAssignableFrom because your code will omit classed that implement your interface indirectly:

 Type interfaceType = typeof(IActionMethod);
 Assembly assembly = Assembly.GetAssembly(interfaceType );
 IEnumerable<System.Type> classes = assembly.GetTypes().Where(x => interfaceType.IsAssignableFrom(x));

Then, you probably want to call:

 methods = cls.GetMethods(...)

because cls is your desired type, you are currently searching in its Type.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1499770

I suspect this is the problem:

foreach(System.Type cls in classes)
{    
    methods = cls.GetType().GetMethods(...)

cls is already a Type, so calling GetType() on it will return System.Type (or a subclass). I suspect you just want:

foreach(System.Type cls in classes)
{    
    methods = cls.GetMethods(...)

It's also unclear why you're clearing the relevant list on each iteration. It means the only entries at the end will be the ones from the last class you look at - are you sure that's what you want?

Upvotes: 9

Related Questions