如何通过反射从不同程序集中调用带有内部委托参数的内部方法?

时间:2019-02-22 14:27:22

标签: c# reflection

我没有类型的源代码,需要使用内部参数调用内部方法。

有没有办法做这样的事情: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;
        }
    }
}

1 个答案:

答案 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 });

假设您已经提供了有关所使用组件的足够信息,并排除了信任级别的任何问题,那么应该做到这一点。