Object property/fields cloner

Here is a class using reflection to transfer property or field values from an object to another, instead of copying values one by one like this:

b.Address = a.Address
b.Age = a.Age
b.Color = a.Color
b.Surname = a.Surname
b.Boss = a.Boss
[...]

Instead, this helper method will be used like this:
PropertyCopier.CopyPropertiesToTargetObject(a,b)

That's it. Object b now have same property values as a.



Imports System.Reflection

''' <summary>
''' Helper class using reflection to copy all fiels and/or properties
''' from a object A to object B
''' </summary>
''' <remarks></remarks>
Public Class PropertyCopier

''' flags to get all instance fields, even privates
Private Shared flags As BindingFlags = BindingFlags.NonPublic Or BindingFlags.[Public] Or BindingFlags.Instance

#Region " To copy object property values "

''' <summary>
''' Copy all property values from sourceObject to targetObject
''' Private and public properties values will be cloned from sourceObject to targetObject when property name exists on the two object
''' </summary>
''' <param name="sourceObject">Oject from which fields values will be copied</param>
''' <param name="targetObject">Object which will have copied property values</param>
''' <remarks>
''' By default, only properties having same value types are cloneed
''' </remarks>
Public Shared Sub CopyPropertiesToTargetObject(ByVal sourceObject As Object, ByVal targetObject As Object)
CopyPropertiesToTargetObject(sourceObject, targetObject, True)
End Sub

''' <summary>
''' Copy all property values from sourceObject to targetObject
''' Private and public properties values will be cloned from sourceObject to targetObject when property name exists on the two object
''' </summary>
''' <param name="sourceObject">Oject from which fields values will be copied</param>
''' <param name="targetObject">Object which will have copied property values</param>
''' <param name="sameValueTypesOnly">If true, only property having the same type of value (ex: String, CustomClassType, etc) will be cloned</param>
''' <remarks></remarks>
Public Shared Sub CopyPropertiesToTargetObject(ByVal sourceObject As Object, ByVal targetObject As Object, ByVal sameValueTypesOnly As Boolean)
'''' getting all properties from two objects
Dim sourceFields As FieldInfo() = sourceObject.[GetType]().GetFields(flags)
Dim targetFields As FieldInfo() = targetObject.[GetType]().GetFields(flags)

Dim tempValue As Object
For Each sourceField As FieldInfo In sourceFields
For Each targetField As FieldInfo In targetFields
If sourceField.Name = targetField.Name Then
'' Same property name => value to copy?
tempValue = sourceField.GetValue(sourceObject)
' If same value type between object, or not strict copy asked
If tempValue.GetType() Is targetField.GetValue(targetObject).GetType() Or Not sameValueTypesOnly Then
Try
targetField.SetValue(targetObject, tempValue)
Catch ex As Exception
If sameValueTypesOnly Then Throw
System.Diagnostics.Debug.WriteLine(ex.ToString())
End Try
End If
End If
Next
Next
End Sub
#End Region

#Region " To copy object fields values "
''' <summary>
''' Copy all fields values from sourceObject to targetObject
''' Private and public field values will be cloned from sourceObject to targetObject when fields name exists on the two object
''' </summary>
''' <param name="sourceObject">Oject from which fields values will be copied</param>
''' <param name="targetObject">Object which will have copied values</param>
''' <remarks>
''' By default, only fields having same value types are cloneed
''' </remarks>
Public Shared Sub CopyFieldsToTargetObject(ByVal sourceObject As Object, ByVal targetObject As Object)
CopyFieldsToTargetObject(sourceObject, targetObject, False)

End Sub
''' <summary>
''' Copy all fields values from sourceObject to targetObject
''' Private and public field values will be cloned from sourceObject to targetObject when fields name exists on the two object
''' </summary>
''' <param name="sourceObject">Oject from which fields values will be copied</param>
''' <param name="targetObject">Object which will have copied values</param>
''' <param name="sameValueTypesOnly">If true, only fields having the same type of value (ex: String, CustomClassType, etc) will be cloned</param>
''' <remarks></remarks>
Public Shared Sub CopyFieldsToTargetObject(ByVal sourceObject As Object, ByVal targetObject As Object, ByVal sameValueTypesOnly As Boolean)
'''' Getting fields from source & target objects
Dim sourceFields As PropertyInfo() = sourceObject.[GetType]().GetProperties(flags)
Dim targetFields As PropertyInfo() = targetObject.[GetType]().GetProperties(flags)
Dim tempValue As Object

'''' Searching match between objects property names
For Each sourceField As PropertyInfo In sourceFields
For Each targetField As PropertyInfo In targetFields
If sourceField.Name = targetField.Name Then
'' Same field name => value to copy?
tempValue = sourceField.GetValue(sourceObject, Nothing)

' If same value type between object, or not strict copy asked
If tempValue.GetType() Is targetField.GetValue(targetObject, Nothing).GetType() Or Not sameValueTypesOnly Then
Try
targetField.SetValue(targetObject, tempValue, Nothing)
Catch ex As Exception
If sameValueTypesOnly Then Throw
System.Diagnostics.Debug.WriteLine(ex.ToString())
End Try
End If

End If
Next
Next
End Sub

#End Region


End Class

1 comment:

nox said...

Hi, thank you vary much for sharing this example, it helped me a lot when I tried to get property values from objects

though I find it's a little overcomplicated, reading and writing properties values would also do (without copying them), the nested loops make it somehow harder to figure out what's going on there, anyway, great job! ;)