代码之家  ›  专栏  ›  技术社区  ›  pm100

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

  •  0
  • pm100  · 技术社区  · 7 年前

    我有一个这样的内部方法

    void Foo(Action<DB> act)
    

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

        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 回复  |  直到 7 年前
        1
  •  0
  •   Neil    7 年前

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

    ConsoleApp项目,引用了类库命名空间 Internal . 我改变了你的想法 dynMethod2.Invoke() Invoke . 还删除了lambda表达式周围的冗余paren。

    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[]{ });
            })
        });
    }
    

    类库 内部的 命名空间。

    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!");
            }
        }
    }
    
        2
  •  0
  •   Mark Feldman    7 年前

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