通过相同对象实例(或基础)的反射调用私有/受保护的方法

dea*_*vmc 10 c# vb.net reflection

是否可以通过反射调用受保护的方法.我用这个:

 Me.GetType.InvokeMember(Stages(CurrentStage), 
                         Reflection.BindingFlags.InvokeMethod, 
                         Nothing, 
                         Me, 
                         Nothing)
Run Code Online (Sandbox Code Playgroud)

总是调用没有参数或返回的方法.我的想法是我的对象的用户(业务逻辑的事务处理)继承基类添加一个私有方法来加载.然后,他们按照他们希望触发的顺序将这些方法名称添加到列表中,上面的代码将负责触发它们.

它适用于公共方法,但不适用于同一类中的私有或受保护方法(受保护,因为我有一些'标准'预构建方法要添加到基类).实际上,我可以将这些方法公之于众,但我内心的书呆子不会允许我这样做......

我假设这是一个安全功能.有没有办法解决这个问题,或者有没有人对如何进行有任何建议,但保持我美味,美味的能见度调节剂?

(注意:ITS在VB.NET中,但如果你觉得这是一个C#答案就好了).

Sam*_*ade 13

如果要在实例化对象上调用方法,则还需要BindingFlags.Instance.所以代码看起来像(注意:我还添加了BindingFlags选项以在搜索中包含公共成员):

Me.GetType.InvokeMember(Stages(CurrentStage), 
                        BindingFlags.InvokeMethod Or BindingFlags.NonPublic Or BindingFlags.Public Or BindingFlags.Instance, 
                        Nothing, 
                        Me, 
                        Nothing)
Run Code Online (Sandbox Code Playgroud)

有关如何使用它的更多信息,请参阅MSDN文档.

编辑

为了支持这个答案,我写了证明的调用一个测试程序public,protected以及private类方法.我已将所有课程上传到PasteBin.组成C#控制台应用程序有三个类,因此可以添加到Visual Studio解决方案并运行以进行测试.

  • Program.cs - 设置要调用的方法(包含在SomeClass类中).执行调用并打印结果.
  • SomeClass.cs -包含每一个可见性修饰符的三种方法:public,protectedprivate.还注册了自己和三个包含的Invoker类调用方法.
  • Invoker.cs - 接受要调用的类型和方法的注册.然后枚举已注册的类型并调用方法,构建可枚举的结果集合.

您可以随意查看该代码,看看您是否可以找到与您接近它的方式有任何区别.我很欣赏它可能不是最简单的方法.如果您对此有任何疑问,请与我们联系.


Jen*_*zlo 5

你可能不需要反思.也许我误解了你想要实现的目标,但听起来你想要将一堆方法注入另一种方法,有点包装它们.您可以将私有方法作为委托参数传递.像这样的东西:

public class Base
{
    protected virtual void Execute(IList<Action> actions = null)
    {
        actions = actions ?? new List<Action>();

        // do stuff like begin tran

        foreach (var action in actions)
        {
            action();
        }

        // do stuff like end tran 
    }
}

public class Sub : Base
{
    protected override void Execute(IList<Action> actions = null)
    {
        actions = actions ?? new List<Action>();
        actions.Add(A);
        actions.Add(B);
        base.Execute(actions);
    }

    private void A()
    {
    }

    private void B()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

Sub的Execute将调用您在Base中编写的代码,然后它将执行A然后执行B,最后执行您在Base中为每个执行的所有内容.