我正在嘗試將源物件的屬性值深度復制到目標物件的同名屬性。我遇到的問題是,如果源屬性是一個集合,在這種情況下是 List(of integer)。它將復制它作為參考,而不是預期的獨立副本,可以在輸出結果中看到。我計劃為作為集合的每個屬性遞回呼叫 Copy 函式,以對該物件進行深層復制。L'ii 還添加了一些關聯代碼。
我遇到的問題是在進行型別比較時我無法檢測到 List(of) 物件 2) 雖然這在進行 Int16 型別比較時有效 1) 我可以在比較 type.Name 時讓它作業 3)
這 3) 足夠健壯還是有辦法使 2) 起作用?
Output:
Unchanged
Source.ID:1 Dest.ID:1
Source.Description:Source Description Dest.Description:Source Description
Source.Links(0):10 Dest.Links(0):10
Source.Links(1):11 Dest.Links(1):11
changed
Source.ID:1 Dest.ID:100
Source.Description:Source Description Dest.Description:Dest Description
Source.Links(0):50 Dest.Links(0):50
Source.Links(1):11 Dest.Links(1):11
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim Source As New DataClass
Dim SourceLinks As New List(Of Integer)({10, 11, 12})
Source.ID = 1
Source.Description = "Source Description"
Source.Links = SourceLinks
Dim Dest As New DataClass
PropertyCopier(Of DataClass, DataClass).Copy(Source, Dest)
Debug.Print("Unchanged")
Debug.Print("Source.ID:" & Source.ID & vbTab & "Dest.ID:" & Dest.ID)
Debug.Print("Source.Description:" & Source.Description & vbTab & "Dest.Description:" & Dest.Description)
Debug.Print("Source.Links(0):" & Source.Links(0) & vbTab & "Dest.Links(0):" & Dest.Links(0))
Debug.Print("Source.Links(1):" & Source.Links(1) & vbTab & "Dest.Links(1):" & Dest.Links(1))
Debug.Print("changed")
Dest.ID = 100
Dest.Description = "Dest Description"
Dest.Links(0) = 50
Debug.Print("Source.ID:" & Source.ID & vbTab & "Dest.ID:" & Dest.ID)
Debug.Print("Source.Description:" & Source.Description & vbTab & "Dest.Description:" & Dest.Description)
Debug.Print("Source.Links(0):" & Source.Links(0) & vbTab & "Dest.Links(0):" & Dest.Links(0))
Debug.Print("Source.Links(1):" & Source.Links(1) & vbTab & "Dest.Links(1):" & Dest.Links(1))
End Sub
End Class
Public Class DataClass
Public Property ID As Int16
Public Property Description As String
Public Property Links As List(Of Integer)
End Class
Public Class PropertyCopier(Of TSource As Class, TDestination As Class)
Public Shared Sub Copy(ByVal Source As TSource, ByVal Destination As TDestination)
Dim SourceProperties = Source.[GetType]().GetProperties()
Dim DestinationProperties = Destination.[GetType]().GetProperties()
For Each SourceProperty In SourceProperties
For Each DestinationProperty In DestinationProperties
If SourceProperty.Name = DestinationProperty.Name AndAlso SourceProperty.PropertyType = DestinationProperty.PropertyType Then
If SourceProperty.PropertyType = GetType(Int16) Then
'1) Correctly detects the property type as a integer
ElseIf SourceProperty.PropertyType = GetType(List(Of)) Then
'2) Does not detect the List(of ) type
ElseIf SourceProperty.PropertyType.Name = GetType(List(Of)).Name Then
'3) Correctly detects the property type as List(of )
End If
If SourceProperty.CanWrite Then DestinationProperty.SetValue(Destination, SourceProperty.GetValue(Source))
Exit For
End If
Next
Next
End Sub
End Class
uj5u.com熱心網友回復:
問題是您的物件的泛型型別引數設定為特定的東西,例如,您正在比較List(Of String)并且List(Of)它們不一樣。您需要做的是從該泛型型別中獲取泛型型別定義,即
ElseIf SourceProperty.PropertyType.IsGenericType AndAlso
SourceProperty.PropertyType.GetGenericTypeDefinition() Is GetType(List(Of)) Then
注意正確的 us ofIs而不是=as well。
uj5u.com熱心網友回復:
根據您需要使用的內容,您可能還希望尋找介面兼容性而不是完全相等。您可以使用Type.IsAssignableFrom. 我有類似的代碼來尋找這樣的串列:
If sourceProperty.PropertyType.IsGenericType _
AndAlso GetType(IList).IsAssignableFrom(sourceProperty.PropertyType) Then
'...
End If
(基于上一個答案)
如果需要,可以使用 eg 獲取泛型型別引數sourceProperty.PropertyType.GenericTypeArguments(0)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/473619.html
下一篇:VSTO致命錯誤System.Runtime.InteropServices.COMException:“來自HRESULT的例外:0x800A03EC”
