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



是否可以通过反射调用受保护的方法。我使用的是:

 Me.GetType.InvokeMember(Stages(CurrentStage), 
                         Reflection.BindingFlags.InvokeMethod, 
                         Nothing, 
                         Me, 
                         Nothing)

它总是调用一个没有params或return的方法。其思想是,我的对象的用户(业务逻辑的事务处理)继承基类,并添加大量要激发的私有方法。然后,他们将这些方法名称按希望它们被激发的顺序添加到列表中,上面的代码将负责激发它们。

它适用于公共方法,但不适用于同一类中的私有或受保护方法(受保护是因为我有一些"标准"预构建方法要添加到基类中)。事实上,我可以公开这些方法,但我内心的书呆子不允许我这么做…

我认为这是一个安全功能。有没有办法绕过这一点,或者有人对如何继续下去有什么建议,但要让我的美味、美味的可见性调节剂保持得体?

(注意:它在VB.NET中,但如果你对此感到满意,C#答案也可以)。

如果您在实例化对象上调用方法,您还需要BindingFlags.Instance。因此,代码如下所示(注意:我还添加了BindingFlags选项,以便在搜索中包括公共成员):

Me.GetType.InvokeMember(Stages(CurrentStage), 
                        BindingFlags.InvokeMethod Or BindingFlags.NonPublic Or BindingFlags.Public Or BindingFlags.Instance, 
                        Nothing, 
                        Me, 
                        Nothing)

有关如何使用它的详细信息,请参阅MSDN文档。

编辑

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

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

请随意查看代码,看看你在处理它的方式上是否有任何不同。不过,我很感激这可能不是最简单的方法。如果您对此有任何进一步的疑问,请告诉我。

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

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()
    {
    }
}

Sub的Execute将调用您在Base中编写的代码,然后执行A,然后执行B,最后执行您在Base的for each之后声明的所有内容。

使用BindingFlags中的NonPublic成员来包含类中的所有方法:

Me.GetType.InvokeMember(Stages(CurrentStage), 
                         BindingFlags.InvokeMethod Or BindingFlags.NonPublic, 
                         Nothing, 
                         Me, 
                         Nothing)

相关内容

  • 没有找到相关文章

最新更新