Я фактически сделал нечто подобное, используя отражение, чтобы помочь с привязкой модели в проекте MVC.Я определил пользовательский атрибут "Updatable" и общий метод расширения.Это немного безопаснее, поскольку я должен явно пометить атрибуты, которые будут клонированы, с моим настраиваемым атрибутом (или через класс метаданных), чтобы поведение могло что-либо делать, но я уверен, что вы могли бы адаптировать его для своих собственных целей.
Вот мой пользовательский атрибут (не очень захватывающий!)
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False)>
Public Class UpdateableAttribute : Inherits Attribute
End Class
А вот и метод расширения
<Extension()>
Public Sub UpdateObject(Of T)(ByVal targetObject As T, ByVal otherObject As T)
Dim metaDataType As MetadataTypeAttribute = GetType(T).GetCustomAttributes(GetType(MetadataTypeAttribute), True).FirstOrDefault
If metaDataType Is Nothing Then
For Each prop As Reflection.PropertyInfo In GetType(T).GetProperties()
If prop.GetCustomAttributes(GetType(UpdateableAttribute), True).Count > 0 Then
Dim targetValue = prop.GetValue(targetObject, {})
Dim otherValue = prop.GetValue(otherObject, {})
If Not targetValue = otherValue Then
prop.SetValue(targetObject, otherValue, {})
End If
End If
Next
Else
Dim targetProps As Reflection.PropertyInfo() = GetType(T).GetProperties()
For Each prop As Reflection.PropertyInfo In metaDataType.MetadataClassType.GetProperties()
If prop.GetCustomAttributes(GetType(UpdateableAttribute), True).Count > 0 Then
Dim propName As String = prop.Name
Dim targetProperty = targetProps.Single(Function(p) p.Name = propName)
Dim targetValue = targetProperty.GetValue(targetObject, {})
Dim otherValue = targetProperty.GetValue(otherObject, {})
If Not targetValue = otherValue Then
targetProperty.SetValue(targetObject, otherValue, {})
End If
End If
Next
End If
End Sub
Хорошо для меня, он, очевидно, использует отражение такне молниеносно, но спасает меня от большого количества левого = правого кодирования.
Если у вас есть доступ к целевому классу, вы можете просто сделать это, в этом примере клонируются только имя и фамилия.
Public Class Person
<Updateable()>
Public Property FirstName As String
<Updateable()>
Public Property Surname As String
Public Property ShoeSize As Integer
Public Property Gender As Gender
Public Property BirthDate As DateTime
Public Property FavoriteCarMake
End Class
И пример использования класса метаданных для того же, что хорошо, если вы не можете редактировать целевой класс напрямую (например, классы Entity Framework, если вам не нравится редактировать шаблоны T4)
<MetadataType(GetType(PersonMetadata))>
Public Class Person
Public Property FirstName As String
Public Property Surname As String
Public Property ShoeSize As Integer
Public Property Gender As Gender
Public Property BirthDate As DateTime
Public Property FavoriteCarMake
End Class
Public Class PersonMetadata
<Updateable()>
Public Property FirstName
<Updateable()>
Public Property Surname
End Class
В обоих случаях вы можете просто сделать что-то вроде этого:
Dim person1 As New Person With ...
Dim person2 As New Person With ...
person1.UpdateObject(person2)