如何使用反射从多级继承类获取受保护的朋友属性

本文关键字:受保护 获取 朋友 属性 继承 何使用 反射 多级 | 更新日期: 2023-09-27 18:34:49

我的类结构有点像这样,

 public class a
       Protected Friend Property ID() As Integer
        Get
            Return _Id
        End Get
        Set(ByVal Value As Integer)
            _Id = Value
        End Set
    End Property 
    //some other properties and methods
 End class

 public class b 
       Inherits a
        //some properties and methods
 End Class

 public class c 
       Inherits b
        //some properties and methods
 End Class
 public class d 
       Inherits c
        //some properties and methods
       Dim obj as D = new D();
       Dim data = obj.GetType().GetProperties(/*I have tried all binding flags here*/) 
 End Class

我想从Class D对象从class a访问ID属性。到目前为止,我用谷歌搜索并从堆栈中找到了很多答案,但这些答案中的任何一个都没有给我想要的东西。

当我使用这样的代码时,我得到该属性,

 'obj.GetType().BaseType.BaseType.BaseType.GetProperties()'

但是使用重复的BaseType属性看起来并不好,而且如果我将来在两者之间添加更多继承,也可能会导致问题。那么有什么办法可以避免这种情况并得到我想要的。如果有任何困惑,请随时发表评论。

附言-我已经尝试了很多关于此的堆栈答案,但无法得到我想要的。如果您知道 C# 方式,那么也请建议我将其转换为 VB。

如何使用反射从多级继承类获取受保护的朋友属性

我在d中创建了一个Sub

Sub DoStuff()
    Dim obj As d = New d()
    Dim data = obj.GetType().GetProperties(BindingFlags.Instance Or BindingFlags.NonPublic)
End Sub

当我单步跳过data行时,data被设置为包含单个属性的数组 - a类中的EntityID属性。

或者,如果我们不想搜索该数组,我们可以直接转到该属性:

Dim eid = obj.GetType().GetProperty("EntityID", _
                                    BindingFlags.Instance Or BindingFlags.NonPublic)

您尚未尝试所有绑定标志。

myD.GetType().GetProperties(
              BindingFlags.NonPublic or _
              BindingFlags.Instance)

应该工作。我做了一个小提琴:https://dotnetfiddle.net/ym0khU

或直接:

myD.GetType().GetProperty("EntityID", 
              BindingFlags.NonPublic or _
              BindingFlags.Instance)

更新:正如@Damien_The_Unbeliever指出的,实例属性不需要FlattenHierarchy

您可以直接访问您的财产

  Module Module1
        Sub Main()
            Dim test As d = New d()
            test.EntityID = 52
            Dim t As Integer = test.EntityID
            Dim t1 As Integer = test.GetEntityID
        End Sub

        Public Class a
            Dim _entityId As Integer
            Protected Friend Property EntityID() As Integer
                Get
                    Return _entityId
                End Get
                Set(ByVal Value As Integer)
                    _entityId = Value
                End Set
            End Property
        End Class

        Public Class b
            Inherits a
        End Class

        Public Class c
            Inherits b
        End Class
        Public Class d
            Inherits c

            Public Function GetEntityID() As Integer
                Dim test As Integer = Me.EntityID
                Return test
            End Function
        End Class
    End Module

感谢您的想法

我尝试添加 GetPropertyName((

它工作正常

        Sub DoStuff()
            Dim obj As d = New d()
            Dim data As PropertyInfo = obj.GetType().GetProperty(GetPropertyName(Function() obj.EntityID), BindingFlags.Instance Or BindingFlags.NonPublic)
            Dim x = data.GetValue(obj, Nothing)
        End Sub
        Public Function GetPropertyName(Of T)(prop As Expression(Of Func(Of T))) As String
            Dim expression = GetMemberInfo(prop)
            Return expression.Member.Name
        End Function
        Private Function GetMemberInfo(method As Expression) As MemberExpression
            Dim lambda As LambdaExpression = TryCast(method, LambdaExpression)
            If lambda Is Nothing Then
                Throw New ArgumentNullException("method")
            End If
            Dim memberExpr As MemberExpression = Nothing
            If lambda.Body.NodeType = ExpressionType.Convert Then
                memberExpr = TryCast(DirectCast(lambda.Body, UnaryExpression).Operand, MemberExpression)
            ElseIf lambda.Body.NodeType = ExpressionType.MemberAccess Then
                memberExpr = TryCast(lambda.Body, MemberExpression)
            End If
            If memberExpr Is Nothing Then
                Throw New ArgumentException("method")
            End If
            Return memberExpr
        End Function