У меня есть класс, в котором есть куча общедоступных методов, и я хотел бы подумать над ним, чтобы найти набор методов-членов, которые могут использоваться как конкретный делегат.
Например:
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}? Если да, то как? Есть ли лучший способ?
В Type нет встроенной поддержки запросов, которая найдет методы, основанные на подписи делегата. Вам нужно будет передать код поисковому методу, который перебирает методы и свойства, вручную сравнивая подписи с предлагаемым делегатом.
Это само по себе является нетривиальной операцией, так как вам нужно принимать общие решения в своем решении.
Это сама по себе нетривиальная операция поскольку вам нужно использовать дженерики в с вашим решением.
100% правильно - не говоря уже о параметрах ref
/out
, модификаторах param[]
, а также небезопасных указателях.
Один неоптимальный вариант заключается в применении Delegate.CreateDelegate
к каждому методу в Entity
, принимая во внимание, когда конструкция завершается с ошибкой. Ошибки обозначают несовместимые методы.
Опять же, вам, вероятно, придется выполнить некоторую работу, чтобы обрабатывать случайные методы.
Здесь начинается:
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 и все остальное. Тестовое развитие было бы особенно полезно здесь.