How to copy object properties to another instance of the same class in C#

March 3, 2010

Copy constructor does exist in C++, but not in C#. There is a great artilce by John Conners dedicated to this issue. It helped me to solve my issue, when i was working on implemention of IEditableObject interface in my ViewModel. Here is the issue. Interface IEditableObject suppose that you will create internal copy of object’s data, while it being edited. If edit operation was canceled, you should restore state of you object. Quite simple. ViewModel always implements INotifyPropertyChanged to notify View about changes. In order to restore View’s state you need to refresh ViewModel properties, not replace internal object. This leads to ugly code, like this:


        public override void CancelEdit()
        {
            if (IsEditing)
            {
                Name = InternalCopy.Name;
                Address= InternalCopy.Address;
                SSN= InternalCopy.SSN;
                //and so on...
                IsEditing = false;
            }
        }


Public Overloads Overrides Sub CancelEdit()
    If IsEditing Then
        Name = InternalCopy.Name
        Address = InternalCopy.Address
        SSN = InternalCopy.SSN
        'and so on...
        IsEditing = False
    End If
End Sub

You can end up with a bunch of properties being copied, but that is not the worst. New properties will not be copied automatically, so you will have tricky bugs in your app. Definitely a solution is needed. It is pretty obvious. I have created class with extension method, which copies all properties using reflection from one instance to another. It perfectly addresses the issue.


    public static class ObjectCopier
    {
        public static void CopyFields<T>(this T dest, T source)
        {
           PropertyInfo[] properties = dest.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

           foreach (PropertyInfo propertyInfo in properties)
            {
                propertyInfo.SetValue(dest, propertyInfo.GetValue(source, null), null);
            } 
        }
    }


Public Module ObjectCopier

    <System.Runtime.CompilerServices.Extension()> _
    Public Sub CopyFields(Of T)(ByVal dest As T, ByVal source As T)
        Dim properties As PropertyInfo() = dest.[GetType]().GetProperties(BindingFlags.[Public] Or BindingFlags.Instance)

        For Each propertyInfo As PropertyInfo In properties
            propertyInfo.SetValue(dest, propertyInfo.GetValue(source, Nothing), Nothing)
        Next
    End Sub

End Module

Look, how clear and cool it became.


        public override void CancelEdit()
        {
            if (IsEditing)
            {
                this.CopyFields(InternalCopy);
                IsEditing = false;
            }
        }


Public Overloads Overrides Sub CancelEdit()
    If IsEditing Then
        Me.CopyFields(InternalCopy)
        IsEditing = False
    End If
End Sub

Advertisement

One Response to “How to copy object properties to another instance of the same class in C#”

  1. Benji said

    Useful, thank you!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.