【问题标题】:How to get properties from nested object using reflection and recursion?如何使用反射和递归从嵌套对象中获取属性?
【发布时间】:2013-12-28 12:53:45
【问题描述】:

我有一组类,它们的属性上有数据注释。其中一些类属性是原始类型(原始也是指字符串、双精度、日期时间等类型),而另一些是自定义类型的属性。

我希望能够遍历类的属性和嵌套对象的属性,并提取每个属性的属性。如果所考虑的类只有一个自定义类型的属性,我已经玩过反射并且我的代码工作正常。 但是,当一个类有多个自定义类型的属性并且每个属性都有其他自定义类型时,我完全不知道如何跟踪已经访问过的对象/属性。

这就是我到目前为止所取得的成就。我在论坛上看到了很多例子,但是它们都有一个简单的嵌套类,每个类最多有一个自定义类型。 以下是我正在尝试完成的示例:

Public Class Claim
    <Required()>
    <StringLength(5)>
    Public Property ClaimNumber As String
    <Required()>
    Public Property Patient As Patient
    <Required()>
    Public Property Invoice As Invoice
End Class

Public Class Patient
    <Required()>
    <StringLength(5)>
    Public Property MedicareNumber As String
    <Required()>
    Public Property Name As String
    <Required()>
    Public Property Address As Address
End Class

Public Class Address
    Public Property Suburb As String
    Public Property City As String
End Class

Public Class Invoice
    <Required()>
    Public Property InvoiceNumber As String
    <Required()>
    Public Property Procedure As String
End Class




 Public Shared Function Validate(ByVal ObjectToValidate As Object) As List(Of String)
          Dim ErrorList As New List(Of String)
             If ObjectToValidate IsNot Nothing Then

               Dim Properties() As PropertyInfo = ObjectToValidate.GetType().GetProperties()
                 For Each ClassProperty As PropertyInfo In Properties
                   Select Case ClassProperty.PropertyType.FullName.Split(".")(0)
                      Case "System" 
                        Dim attributes() As ValidationAttribute = ClassProperty.GetCustomAttributes(GetType(ValidationAttribute), False)
                                For Each Attribute As ValidationAttribute In attributes
                                    If Not Attribute.IsValid(ClassProperty.GetValue(ObjectToValidate, Nothing)) Then
                                        ErrorList.Add("Attribute Error Message")
                                    End If
                                Next
                            Case Else
                                Validate(ClassProperty.GetValue(ObjectToValidate, Nothing))
        **** ‘At this point I need a mechanism to keep track of the parent of ClassProperty and also mark ClassProperty as visited, so that I am able to iterate through the other properties of the parent (ObjectToValidate), without revisiting ClassProperty again.**

                        End Select
                    Next
                End If
                Return Nothing
            End Function

【问题讨论】:

    标签: vb.net object reflection recursion


    【解决方案1】:

    解决此问题的最直接(可能也是最简单)的方法是保留一个由类名作为键的类属性属性字典。

    如果我接近这个,我可能会创建一个类来保存属性属性:

    Public Class PropertyAttribute
       Public PropertyName As String
       Public PropertyTypeName As String
       Public Required As Boolean
       Public StringLength As Integer
    End Class
    

    然后创建一个类来保存每个类的属性信息:

    Public Class ClassAttributes
       Public ClassName As String
       ' You could also use a dictionary here to key properties by name
       Public PropertyAttributes As New List(Of PropertyAttribute)
    End Class
    

    最后,创建一个 ClassAttributes 字典来跟踪您已经处理了哪些自定义类:

    Public ProcessedClasses As New Dictonary(Of String, ClassAttributes)
    

    字典的键是类名。

    当您通过反射处理属性时,如果属性类型是自定义的,请检查字典中是否存在该类。如果它在那里,您不必处理它。

    如果不存在,立即将新实例添加到字典中(以便安全处理相同类型的嵌套对象),然后处理类的属性。

    【讨论】:

    • 我喜欢你的想法,即有一个字典来保存之前处理过的所有类。但我看不出让类拥有属性属性和类属性的意义。
    • @Laavanya:property 属性类只是基于我们在自己的应用程序中如何使用类似信息的一个想法(在启动时处理类并全局缓存发现的信息,然后使用它来配置 UI或传入文档验证业务规则)。如果您不需要这种方法,绝对没有理由使用它们。
    • 我喜欢你的想法,即有一个字典来保存之前处理过的所有类。但我看不出让类拥有属性属性和类属性的意义。还想知道我是否可以消除整个验证方法,并在每个属性的集合上实现 IsValid 方法,并在设置属性时验证该属性。如果属性未通过其属性指定的验证,该类可以维护一个错误列表,它可以在设置属性时更新该列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-11
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    相关资源
    最近更新 更多