C# 如何使用反射从多级继承类获取受保护的好友属性?
我的班级结构有点像这样C# 如何使用反射从多级继承类获取受保护的好友属性?,c#,vb.net,reflection,properties,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
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 您可以直接访问您的财产
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
您可以直接访问您的财产
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
我在
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)
我在
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)
应该有用。我做了一把小提琴:
或直接:
myD.GetType().GetProperty("EntityID",
BindingFlags.NonPublic or _
BindingFlags.Instance)
更新:正如@Damien\u异教徒指出的那样,
flatthierarchy
对于实例属性是不必要的您还没有尝试所有绑定标志
myD.GetType().GetProperties(
BindingFlags.NonPublic or _
BindingFlags.Instance)
应该有用。我做了一把小提琴:
或直接:
myD.GetType().GetProperty("EntityID",
BindingFlags.NonPublic or _
BindingFlags.Instance)
更新:正如@Damien\u异教徒指出的那样,
扁平化层次结构
对于实例属性来说是不必要的谢谢你的想法
我尝试添加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
谢谢你的想法
我尝试添加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
请说明原因?您可以直接访问d类中的EntityID属性。或者我不明白你的问题。您可以在方法或属性中访问EntityID,这是示例代码中C#和VB的混淆组合(例如,它看起来像VB,但有C#风格的注释和零散的
(另外,“如果底部的代码在有效块内,例如子或函数,则效果更好”)@Damien#u不信教者很抱歉,基本上我是c#coder最近开始使用VB,所以在这里输入时出现了旧习惯。很抱歉。请说明原因?您可以直接访问d类中的EntityID属性。或者我不理解您的问题。您可以通过方法或属性访问EntityID示例代码中C#和VB的混淆组合(例如,它看起来像VB,但有C#风格的注释和零散的
(另外,“如果底部的代码在有效块内,例如子或函数,则效果更好”)@Damien#u The#u The#u unsivers抱歉,基本上我是c#coder最近开始使用VB,所以在这里输入时出现了旧习惯。抱歉。因为问题被标记,标题以“使用反射”结尾,我想他们在这里寻找基于反射的答案。抱歉,现在我明白了,因为问题被标记,标题以“使用反射”结尾,我想他们在这里寻找基于反射的答案。抱歉,现在我明白了这里不需要flatthierarchy
。它只与静态相关(或者用VB的说法是Shared
)@Damien\u不相信你是完全正确的,而且,现在我读到了,你的答案已经是正确的。让我更新并更新你的答案Shared
在这里不是必需的。它只与静态相关(或者用VB的说法是Shared
)@Damien_,不相信你的人,你是完全正确的,而且,现在我读了,你的答案已经是正确的。让我更新并更新你的答案