Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 如何使用反射和递归从嵌套对象获取属性?_Vb.net_Object_Reflection_Recursion - Fatal编程技术网

Vb.net 如何使用反射和递归从嵌套对象获取属性?

Vb.net 如何使用反射和递归从嵌套对象获取属性?,vb.net,object,reflection,recursion,Vb.net,Object,Reflection,Recursion,我有一组类,它们的属性上有数据注释。这些类属性中的一些是基元类型(基元也指字符串、双精度、日期时间等类型),而另一些是自定义类型的属性 我希望能够遍历类的属性和嵌套对象的属性,并提取每个属性的属性。如果所考虑的类只有一个自定义类型的属性,那么我已经使用了反射,我的代码工作得很好。 但是,当一个类有多个自定义类型的属性,并且每个属性都有其他自定义类型时,我完全不知道如何跟踪已经访问过的对象/属性 这就是我到目前为止取得的成绩。我在论坛上看到了很多例子,但它们都有一个简单的嵌套类,每个类最多有一个自

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

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

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

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
公共类索赔
公共属性ClaimNumber作为字符串
公共财产病人作为病人
作为发票的公共财产发票
末级
公立病人
公共属性重新编号为字符串
作为字符串的公共属性名称
公共财产地址
末级
公共课堂演讲
作为字符串的公共财产
作为字符串的公共财产城市
末级
公共类发票
公共属性InvoiceNumber作为字符串
作为字符串的公共属性过程
末级
公共共享函数验证(ByVal ObjectToValidate As Object)作为列表(字符串)
Dim ErrorList作为新列表(字符串)
如果ObjectToValidate不是空的,那么
Dim Properties()作为PropertyInfo=ObjectToValidate.GetType().GetProperties()
将每个ClassProperty作为PropertyInfo存储在Properties中
选择案例ClassProperty.PropertyType.FullName.Split(“.”)(0)
案例“系统”
Dim attributes()作为ValidationAttribute=ClassProperty.GetCustomAttributes(GetType(ValidationAttribute),False)
将每个属性作为属性中的ValidationAttribute
如果不是Attribute.IsValid(ClassProperty.GetValue(ObjectToValidate,Nothing)),则
ErrorList.Add(“属性错误消息”)
如果结束
下一个
其他情况
验证(ClassProperty.GetValue(ObjectToValidate,Nothing))
****'此时,我需要一种机制来跟踪ClassProperty的父级,并将ClassProperty标记为已访问,这样我就可以迭代父级的其他属性(ObjectToValidate),而无需再次访问ClassProperty**
结束选择
下一个
如果结束
一无所获
端函数
实现这一点最直接(可能也是最简单)的方法是保留一个由类名键入的类属性字典

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

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)
字典的关键是类名

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


如果没有,请立即向字典中添加一个新实例(以便安全地处理相同类型的嵌套对象),然后处理该类的属性。

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