2017-04-13 106 views
0

假定以下示例類其模擬從XSD文件生成的類的類型:在不調用構造函數的情況下遞歸地實例化子類?

Public Class MyClass 
    Public Class MyInnerClass1 
     Public Class MyInnerInnerClass1 
      Public Property MyProp1 as string 
      Public Property MyProp2 as string 
      ... 
     End Class 
     ... 
     Public Property MyInnerInnerClassProp1 as MyInnerInnerClass1 
    End Class 

    Public property MyInnerClassProp1 as MyInnerClass1 
    Public property MyInnerClassProp2 as MyInnerClass2 
    ... 
End Class 

注意,沒有構造函數。在觸及基本屬性(如Property MyProp1 as string)之前,內部類的級別(在此特定情況下)可能會循環深入5個級別。

如何遞歸遍歷所有公共可寫屬性,並將它們初始化爲沒有構造函數的對象類型的新實例?

例如,這裏是我現在的代碼,目前只能深入一層。

Private Shared Sub InitProperties(obj As Object) 
    For Each prop As Object In obj.[GetType]().GetProperties(BindingFlags.[Public] Or BindingFlags.Instance).Where(Function(p) p.CanWrite) 
     Dim type__1 = prop.PropertyType 
     Dim constr = type__1.GetConstructor(Type.EmptyTypes) 
     'find paramless const 
     If type__1.IsClass Then 
      Dim propertyInstance = DirectCast(FormatterServices.GetUninitializedObject(type__1.GetType()), Object) 

      'Dim propInst = Activator.CreateInstance(type__1) 
      'prop.SetValue(obj, propInst, Nothing) 
      InitProperties(propertyInstance) 
     End If 
    Next 
End Sub 

回答

0

我對你的代碼做了一些小的修改,以使它適用於你提供的示例類。 (雖然我確實將字符串屬性更改爲Integer以避免出現一個錯誤。)我還添加了一個用於限制遞歸調用數的參數,並且在初始化它之前檢查屬性是否等於Nothing。 (如果您在靜態類之間有循環引用,則此檢查僅起作用。)

Private Shared Sub InitProperties(obj As Object, Optional ByVal depth As Integer = 5) 
    For Each prop As PropertyInfo In obj.GetType().GetProperties(BindingFlags.Public Or BindingFlags.Instance).Where(Function(p) p.CanWrite) 
     Dim type__1 As Type = prop.PropertyType 

     If type__1.IsClass And IsNothing(prop.GetValue(obj, Nothing)) And depth > 0 Then 
      Dim propertyInstance As Object = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type__1) 
      prop.SetValue(obj, propertyInstance, Nothing) 
      InitProperties(propertyInstance, depth - 1) 
     End If 
    Next 
End Sub 
相關問題