我没有类型的源代码,需要使用内部参数调用内部方法。
有没有办法做这样的事情:Set.InOrderTreeWalk((object o) => o != null)
?
namespace assembly_1
{
internal delegate bool TreeWalkPredicate<T>(Set<T>.Node node);
public class Set<T>
{
private Node[] nodes;
internal bool InOrderTreeWalk(TreeWalkPredicate<T> action)
{
foreach (var node in nodes)
{
if (!action(node))
return false;
}
return true;
}
internal class Node
{
public T Item;
}
}
}
答案 0 :(得分:1)
在开始讨论之前,插入关于实施细节如何内部存在的标准免责声明是有原因的,如果某些事情发生变化并且破坏了您的反射代码,作者不会欠您任何解释。 >
从表面上看,该参数是内部委托类型的事实确实使此操作有些麻烦,但是实际上有一种方便的方式来获取它:为要调用的方法获取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 });
假设您已经提供了有关所使用组件的足够信息,并排除了信任级别的任何问题,那么应该做到这一点。