Прежде чем я углублюсь в это, вставьте стандартный отказ от ответственности о том, как детали реализации являются внутренними по какой-то причине, и автор не должен вам объяснять, если что-то изменится и это нарушит ваш код отражения.
На первый взгляд, тот факт, что аргумент имеет внутренний тип делегата, делает это немного проблематичным, но на самом деле есть удобный способ его получить: получить MethodInfo
для метода, который мы хотим вызватьи затем исследуем его параметр.
Давайте предположим, что у нас уже есть эта переменная с назначенным экземпляром:
Set<MyNode> set;
... и что тип MyNode
был объявлен где-то.Мы хотим, чтобы Set<MyNode>.InOrderTreeWalk
вызывал следующий метод для каждого узла в наборе:
private bool MyPredicate(Set<MyNode>.Node node)
{
return true;
}
Ничего особенного, просто следуйте комментариям:
// Get the method we want to call.
MethodInfo inOrderTreeWalkMethod = set.GetType().GetMethod(
"InOrderTreeWalk", BindingFlags.NonPublic | BindingFlags.Instance);
// Get the internal delegate type from the parameter info. The type retrieved here
// is already close-constructed so we don't have to do any generic-related manipulation.
Type treeWalkPredicateType = inOrderTreeWalkMethod.GetParameters()[0].ParameterType;
// Get the method we want to be called for each node.
MethodInfo myPredicateMethod = GetType().GetMethod(
nameof(MyPredicate), BindingFlags.NonPublic | BindingFlags.Instance);
// Create the delegate. This is where the magic happens. The runtime validates
// type compatibility and throws an exception if something's wrong.
Delegate myPredicateDelegate = myPredicateMethod.CreateDelegate(treeWalkPredicateType, this);
// Call the internal method and pass our delegate.
bool result = (bool)inOrderTreeWalkMethod.Invoke(set, new object[] { myPredicateDelegate });
Предполагая, что выпредоставил достаточно информации о компоненте, который вы используете, и за исключением проблем с уровнем доверия, которые должны это сделать.