[英]How to call internal method with internal delegate argument from different assembly by reflection?
I do not have a source code for a type and need to call an internal method with an internal argument. 我没有类型的源代码,需要使用内部参数调用内部方法。
Is there a way to do something like this: Set.InOrderTreeWalk((object o) => o != null)
? 有没有办法做这样的事情:
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;
}
}
}
Before I get into it, insert standard disclaimer about how implementation details are internal for a reason and the author doesn't owe you an explanation if something changes and it breaks your reflection code. 在我开始讨论之前,请插入一个标准的免责声明,说明实施细节如何内部存在的原因,并且作者不会欠您任何解释,以防发生某些更改并破坏了反射代码。
On the surface, the fact that the argument is of an internal delegate type does make this a bit troublesome, but there's actually a convenient way to get it: get the MethodInfo
for the method we want to call and then examine its parameter. 从表面上看,参数是内部委托类型的事实确实使这有些麻烦,但是实际上有一种方便的方法来获取它:获取要调用的方法的
MethodInfo
,然后检查其参数。
Let's assume we already have this variable with an instance assigned: 假设我们已经为这个变量分配了一个实例:
Set<MyNode> set;
...and that the MyNode
type has been declared somewhere. ...并且
MyNode
类型已在某处声明。 We want Set<MyNode>.InOrderTreeWalk
to call the following method for each node in the set: 我们希望
Set<MyNode>.InOrderTreeWalk
为集合中的每个节点调用以下方法:
private bool MyPredicate(Set<MyNode>.Node node)
{
return true;
}
There's not much to it, just follow the comments: 没什么大不了的,只需遵循以下注释即可:
// 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 });
Assuming you've provided enough information about the component you're using, and barring any issues with trust level, that should do it. 假设您已经提供了有关正在使用的组件的足够信息,并且排除了信任级别的任何问题,那么应该做到这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.