如何使用反射从多级继承类获得Protected Friend proprty?

时间:2016-02-16 08:10:30

标签: c# vb.net reflection properties

我的课程结构有点像这样,

 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

我想从ID的对象访问class a的{​​{1}}属性。直到现在我用Google搜索并从堆栈中找到了很多答案,但这些答案都没有给我我想要的东西。

当我使用像

这样的代码时,我得到了这个属性
Class D

但重复 'obj.GetType().BaseType.BaseType.BaseType.GetProperties()' 属性的使用并不好看,如果我将来添加更多继承,也可能会导致问题。所以有什么方法可以避免这种情况并获得我想要的东西。如有任何疑惑,请随时发表评论。

P.S-我已经尝试了很多关于此的堆栈答案,但却无法得到我想要的东西。如果你知道C#方式,那么请建议我将它转换为VB。

4 个答案:

答案 0 :(得分:3)

我在Sub中创建了d

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

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

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

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

答案 1 :(得分:2)

您尚未尝试过所有绑定标记。

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

答案 2 :(得分:1)

您可以直接访问您的财产

  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

答案 3 :(得分:0)

感谢您的想法

我尝试添加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