无法反映私有方法 [英] Can't reflect on Private Methods

查看:37
本文介绍了无法反映私有方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我创建了这个线程:通过来自同一对象实例(或基)的反射调用私有/受保护的方法

So I created this thread: Invoking Private / Protected Methods Via Reflection From The Same Object Instance (or Base)

除私有方法外,我们解决了问题.由于这可能不是同一个问题,我认为最好用完整的来源发布一个不同的问题.它仍在进行中,但功能齐全.

And we got the problem fixed save for private methods. As this may not be the same issue I thought it may be best to post a different question with the full source. It is still a work in progress but it is functional.

基类:

Public MustInherit Class BaseTransactionalSaveManager : Implements ITransactionalSaveManager

    '---- Public Properties & Backing Fields ----'

    Public Property FormDataIsValid As Boolean Implements ITransactionalSaveManager.FormDataIsValid

    '---- Private Properties & Backing Fields ----'

    Protected Property Stages As Collections.Generic.List(Of String)
    Protected Property StageCausedRollback As Containers.GenericNamedValuePair(Of String, Boolean)
    Protected Property CurrentStage As Integer

    '---- Event Declarations & Associated Methods ----'

    Public Event TransactionCancelled As EventHandler(Of CustomEventArgs.GenericSingleEventArgs(Of String)) Implements ITransactionalSaveManager.TransactionCancelled

    Public Event TransactionCompleted As EventHandler(Of CustomEventArgs.GenericSingleEventArgs(Of String)) Implements ITransactionalSaveManager.TransactionCompleted

    Public Event TransactionStagePassed As EventHandler(Of CustomEventArgs.GenericSingleEventArgs(Of String)) Implements ITransactionalSaveManager.TransactionStagePassed

    Protected Overridable Sub OnTransactionCancelled(e As CustomEventArgs.GenericSingleEventArgs(Of String)) Implements ITransactionalSaveManager.OnTransactionCancelled

        RaiseEvent TransactionCancelled(Me, e)

    End Sub

    Protected Overridable Sub OnTransactionCompleted(e As CustomEventArgs.GenericSingleEventArgs(Of String)) Implements ITransactionalSaveManager.OnTransactionCompleted

        RaiseEvent TransactionCompleted(Me, e)

    End Sub

    Protected Overridable Sub OnTransactionStagePassed(e As CustomEventArgs.GenericSingleEventArgs(Of String)) Implements ITransactionalSaveManager.OnTransactionStagePassed

        RaiseEvent TransactionStagePassed(Me, e)

    End Sub

    '---- Constructors ----'

    Public Sub New()

        Stages = New Collections.Generic.List(Of String)
        SetStages()
        CurrentStage = 0

        StageCausedRollback = New Containers.GenericNamedValuePair(Of String, Boolean)
        FormDataIsValid = True

    End Sub

    '---- Public Methods ----'

    Public Sub ProcessStage() Implements ITransactionalSaveManager.ProcessStage

        ' Use stage to fire the correct method.

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

        ' Determine if the stage should cause a rollback.

        If Not StageCausedRollback.Value Then

            RollBackTransaction(StageCausedRollback.Name)
            Exit Sub

        End If

        ' Check if this stage is the last one.

        If Stages(CurrentStage) = Stages.Last Then

            OnTransactionCompleted(New CustomEventArgs.GenericSingleEventArgs(Of String)(Stages(CurrentStage)))

        Else

            OnTransactionStagePassed(New CustomEventArgs.GenericSingleEventArgs(Of String)(Stages(CurrentStage)))

        End If

    End Sub

    Public Overridable Function TryCancelTransaction() As Boolean Implements ITransactionalSaveManager.TryCancelTransaction

        OnTransactionCancelled(New CustomEventArgs.GenericSingleEventArgs(Of String)(""))
        Return True

    End Function

    '--- Protected & Overridable Methods ----'

    Protected Overridable Sub SetStages()

        Me.Stages.Add(MethodNameToString(AddressOf Me.ConfirmFormDataIsValid))

    End Sub

    Protected Overridable Sub RollBackTransaction(stageThatCauseRollback As String)

        OnTransactionCancelled(New CustomEventArgs.GenericSingleEventArgs(Of String)(stageThatCauseRollback))

    End Sub

    Protected Function MethodNameToString(addressOfMethod As Action) As String

        Return addressOfMethod.Method.Name

    End Function

    Private Sub ConfirmFormDataIsValid()

        StageCausedRollback.Name = MethodNameToString(AddressOf ConfirmFormDataIsValid)
        StageCausedRollback.Value = If(FormDataIsValid, True, False)

    End Sub

End Class

所以这个类被一个(到目前为止)空的子类继承,并且正在调用 ProcessStage.请注意 ConfirmFormDataIsValid() sub 是私有的.如果你运行它,它不会找到这个方法.如果我将其更改为受保护,则它可以正常工作.

So this class is being inherited by a (so far) empty child class and ProcessStage is being called. Notice that ConfirmFormDataIsValid() sub is private. If you run this it will not find this method. If I change it to protected however it works fine.

我错过了什么吗?

推荐答案

需要调用 Me.GetType.BaseType 而不是 Me.GetType.InvokeMember(ProcessStage 的第一行).InvokeMember

Instead of Me.GetType.InvokeMember (first line of ProcessStage), you need to call Me.GetType.BaseType.InvokeMember

即使使用 BindingFlags.NonPublic,您也不会在子类中看到私有成员.

You won't see private members in subclasses, even with BindingFlags.NonPublic.

显然,该解决方案会有点脆弱,因为这取决于您是否会在 BaseType 中看到该方法的子类级别.您可能需要循环类链,直到到达 BaseTransactionalSaveManager 的 BaseType,然后找到方法.

Obviously that solution will be a bit fragile, as it depends how many levels of subclasses you have as to whether you will see the method in the BaseType or not. You might need to loop up the chain of classes until you reach a BaseType of BaseTransactionalSaveManager and then find the method.

希望有所帮助.

这篇关于无法反映私有方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆