首页 > 解决方案 > 通过采用 Action 的反射调用方法. 所有方法、包含类和 T 都标记为内部

问题描述

我有这样的内部方法

void Foo(Action<DB> act)

类 DB 在同一个程序集中,也标记为内部。我可以弄清楚如何获取 Foo 的方法信息,但我无法弄清楚如何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=>{

但我不能这样做(数据库是内部的),object编译但在运行时失败,说对象的类型错误。

标签: c#reflection

解决方案


我对您的示例进行了很少的更改,并获得了可以编译并运行完成的代码。您的 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!");
        }
    }
}

推荐阅读