mercredi 11 octobre 2017

Type.GetMethod() for generic method

For testing purposes, I'm checking to see if a series of method signatures in a reference class have been implemented on a different static class. For most of them the following is working:

private static IEnumerable<Signature> GetMethodSigs(Type type)
{
    // Get MethodInfos, filter and project into signatures
    var methods = type.GetMethods(
                          BindingFlags.Public
                        | BindingFlags.DeclaredOnly
                        | BindingFlags.Static 
                        | BindingFlags.Instance)
                    .Where(mi => !mi.Name.StartsWith("get_"))
                    .Where(mi => !mi.Name.StartsWith("set_"))
                    .Select(o => new Signature(o.Name, o.ReturnType, o.GetParameters().Select(pi => pi.ParameterType)));

    return methods;
}

private MethodInfo FindMethod(Type type, Signature sig)
{
    MethodInfo member = type.GetMethod(
                                sig.Name,
                                BindingFlags.Public | BindingFlags.Static,
                                null,
                                sig.ParameterTypes.ToArray(),
                                null);
    return member;
}

public struct Signature
{
    public string Name;
    public Type ReturnType;
    public IEnumerable<Type> ParameterTypes;

    public Signature(string name, Type returnType, IEnumerable<Type> parameterTypes = null)
    {
        Name = name;
        ReturnType = returnType;
        ParameterTypes = parameterTypes;
    }
}

This is part of a test class, but imagine the following code driving the process:

foreach(var sig in GetMethodSigs(typeof(ReferenceClass)))
    Console.WriteLine(FindMethod(typeof(TestClass), sig)?.ToString());

The following method signature is being picked up okay on ReferenceClass, but FindMethod() is not finding an equivalent method (which does exist!) on TestClass:

public static void SomeMethod<T>(SomeDelegate<T> del)

GetMethods() gives me a type for the del parameter (SomeDelegate`1), but this is apparently not a suitable type to search on in GetMethod(), as FindMethod() returns null for this input.

Any idea how I can manipulate the values returned from GetMethods() to search for a generic method using GetMethod() (with the obvious subtlety that the generic parameter is used in a delegate, rather than a simple parameter type)?

(I realise there is a version of GetMethod() just taking a name, but as some of the method names are overloaded, I need to search for the parameter types as well.)





Aucun commentaire:

Enregistrer un commentaire