通过采用Action <t>的反射调用方法。所有方法,包含的类和T都标记为内部

时间:2018-11-12 19:21:58

标签: c# reflection

我有这样的内部方法

void Foo(Action<DB> act)

类DB在同一程序集中,并且也标记为内部。我可以解决如何获取Foo的methodinfo的方法,但是无法解决如何在调用代码中设置回调act的方法。到目前为止,这就是我所拥有的(作为一种附加的香料,我想从回调内部调用另一个内部方法)

    var tt = eng.GetType().Assembly;
    var dd = tt.GetType("Internal.DB");
    var kk = typeof(Action<>);
    Type[] targs =  { dd };
    var qq = kk.MakeGenericType(targs);
    MethodInfo dynMethod = eng.GetType().GetMethod("Foo", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { qq },null);
    dynMethod.Invoke(this, new object[] {
        ((Action<object>)(db=>{
       MethodInfo dynMethod2 = db.GetType().GetMethod("Wiz", BindingFlags.NonPublic | BindingFlags.Instance);
        dynMethod2.Invoke(db);
    })) }); 

我的问题在这里(我认为)

((Action<object>)(db=>{

我真的需要

((Action<DB>)(db=>{

但是我不能这样做(DB是内部的),带有object的那个可以编译,但是在运行时失败,说明该对象的类型错误。

2 个答案:

答案 0 :(得分:0)

我对您的示例所做的更改很少,并且得到了可以编译并运行完成的代码。您的DB.Wiz()是否有可能引发异常?如果不是这样,我们可能需要更多有关哪个运行时给您这个问题的信息,或者提供更完整的示例。下面的示例正确输出"Hello, World!"

.Net 4.6.1解决方案

ConsoleApp项目,已引用类库名称空间Internal。我将您的dynMethod2.Invoke()更改为传递一个空对象[],因为您的示例未使用一个参数编译到Invoke。还删除了lambda表达式周围的多余括号。

private static void Main(string[] args)
{
    Internal.Eng eng = new Internal.Eng();

    var tt = eng.GetType().Assembly;
    var dd = tt.GetType("Internal.DB");
    var kk = typeof(Action<>);
    Type[] targs = { dd };

    var qq = kk.MakeGenericType(targs);

    MethodInfo dynMethod = eng.GetType().GetMethod("Foo", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { qq }, null);

    dynMethod.Invoke(eng, new object[] {
        (Action<object>)(db=>{
            MethodInfo dynMethod2 = db.GetType().GetMethod("Wiz", BindingFlags.NonPublic | BindingFlags.Instance);
            dynMethod2.Invoke(db, new object[]{ });
        })
    });
}

类库Internal命名空间。

using System;

namespace Internal
{
    public class Eng
    {
        internal void Foo(Action<DB> act) => act(new DB());
    }

    internal class DB
    {
        internal void Wiz()
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

答案 1 :(得分:0)

很难确切地知道您要执行的操作,但是如果Wiz是不接受任何参数的DB方法,那么我相信您会遵循以下要求:

dynMethod.Invoke(this, new object[] {
    ((Action<DB>)(db=> {
        MethodInfo dynMethod2 = db.GetType().GetMethod("Wiz", BindingFlags.NonPublic | BindingFlags.Instance);
        dynMethod2.Invoke(db, null);
})) });