繁体   English   中英

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

[英]calling method via reflection that takes an Action<T>. All of the method, the containing class and T are marked internal

我有这样的内部方法

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那个可以编译,但是在运行时失败,说明该对象的类型错误。

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

确切地了解您要执行的操作有点困难,但是如果Wiz是不接受任何参数的DB方法,那么我相信您正在执行以下操作:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM