简体   繁体   中英

How can I use reflection in C# to find all the members of a class that meet the requirements of a specific delegate?

I've got a class that's got a bunch of public methods, and I'd like to reflect over it to find the set of member methods that could be used as a particular delegate.

For example:

delegate void InterestingFunc(int i);

class Entity
{
    public void F();
    public void G();
    public void H(int i);
    public void X(int i);
}

Can I use Type.FindMembers() to pull out the set { H, X }? If so, how? Is there a better way?

There is no inherent query support in Type which will find methods based on a delegate signature. You would need to hand code a search method which loops through methods and properties manually comparing the signatures to that of the proposed delegate.

This itself is a non-trivial operation as you need to take generics into account with your solution.

This itself is a non-trivial operation as you need to take generics into account with your solution.

100% correct -- not to mention ref / out parameters, param[] modifiers, as well as unsafe pointers.

One non-optimal option is to apply Delegate.CreateDelegate to each method in Entity , taking note of when the construction fails. The failures denote the incompatible methods.

Again, you will likely have to do some work to handle the case of generic methods.

Here's a start:

   MethodInfo[] FindMethods(Type delegateType, Type sourceType)
    { 
      var dInfo       = delegateType.GetMethod("Invoke");
      var dParamTypes = delegateInfo.GetParameters().Select(p=>p.ParameterType);

      var methods = from methodInfo in sourceType.GetMethods()
                    let mParamTypes = methodInfo.GetParameters()
                                                .Select(p=>p.ParameterType)
                    where    methodInfo.ReturnType == delegateInfo.ReturnType
                          && mParamTypes.SequenceEqual(dParamTypes)
                    select methodInfo;

      return methods.ToArray();
    }

It can be expanded to take into account generics, ref/out parameters, and anything else. Test-driven development would be particularly helpful here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM