Как я могу использовать отражение в C #, чтобы найти всех членов класса, которые отвечают требованиям конкретного делегата?

2

У меня есть класс, в котором есть куча общедоступных методов, и я хотел бы подумать над ним, чтобы найти набор методов-членов, которые могут использоваться как конкретный делегат.

Например:

delegate void InterestingFunc(int i);

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

Можно ли использовать Type.FindMembers(), чтобы вытащить набор {H, X}? Если да, то как? Есть ли лучший способ?

Теги:
delegates
reflection

3 ответа

4
Лучший ответ

В Type нет встроенной поддержки запросов, которая найдет методы, основанные на подписи делегата. Вам нужно будет передать код поисковому методу, который перебирает методы и свойства, вручную сравнивая подписи с предлагаемым делегатом.

Это само по себе является нетривиальной операцией, так как вам нужно принимать общие решения в своем решении.

1

Это сама по себе нетривиальная операция поскольку вам нужно использовать дженерики в с вашим решением.

100% правильно - не говоря уже о параметрах ref/out, модификаторах param[], а также небезопасных указателях.

Один неоптимальный вариант заключается в применении Delegate.CreateDelegate к каждому методу в Entity, принимая во внимание, когда конструкция завершается с ошибкой. Ошибки обозначают несовместимые методы.

Опять же, вам, вероятно, придется выполнить некоторую работу, чтобы обрабатывать случайные методы.

1

Здесь начинается:

   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();
    }

Он может быть расширен, чтобы принимать во внимание дженерики, параметры ref/out и все остальное. Тестовое развитие было бы особенно полезно здесь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню