Combining Objects in C#

There has been a few times I’ve need to copy models to view models, or very similar classes to each other, but wanted to clean up the code in the process. The result of that is a start to a helper method below to “combine” objects in C#. Code will stay static on this post. To retrieve updated code, visit via GitHub.

public static class ObjectJoin
    {
        /// <summary>
        /// Attempts to combine values from two different objects with the same property names into one object
        /// </summary>
        /// <param name="firstObject">The object in which we will return with combined values</param>
        /// <param name="secondObject">The object in which we will be pulling values from</param>
        /// <param name="sourceOverwrite">If we overwrite the value from the first object if one already exists (Default is true)</param>
        /// <returns>The first object with combined values from the second object</returns>
        public static object JoinObjects(object firstObject, object secondObject, bool sourceOverwrite = true)
        {
            if(firstObject == null || secondObject == null)
            {
                throw new ArgumentException("One of the objects passed to JoinObjects is null");
            }

            // Read in first object information
            var firstObjectHash = GetObjectPropertyHash(firstObject);

            // Read in the second object information
            var secondObjectHash = GetObjectPropertyHash(secondObject);

            foreach (var item in firstObjectHash)
            {
                if (secondObjectHash.ContainsKey(item.Key) && (secondObjectHash[item.Key] != null || sourceOverwrite))
                {
                    SetObjectProperty(ref firstObject, item.Key, secondObjectHash[item.Key]);
                }                
            }
            return firstObject;
        }

        /// <summary>
        /// Retrieves the parameter and value list of an inputed object
        /// </summary>
        /// <param name="obj">The object which to identify the properties and values</param>
        /// <returns>A dictionary of the parameter names as the key, and property values as values</returns>
        private static Dictionary<string,object> GetObjectPropertyHash(object obj)
        {
            Type objType = obj.GetType();
            Dictionary<string, object> hashTable = new Dictionary<string, object>();
            foreach (PropertyInfo property in objType.GetProperties())
            {
                hashTable.Add(property.Name, property.GetValue(obj, null));
            }
            return hashTable;
        }

        /// <summary>
        /// Attempts to set a value to a property dynamically 
        /// </summary>
        /// <param name="obj">The object which you are dynamically setting a property to</param>
        /// <param name="propertyName">The name of the objects property to assign the value to</param>
        /// <param name="value">The value to assign to the object's property</param>
        private static void SetObjectProperty(ref object obj, string propertyName, object value)
        {
            PropertyInfo propertyInfo = obj.GetType().GetProperty(propertyName);            
            if (propertyInfo != null && value != null && propertyInfo.GetSetMethod() != null)
            {
                try
                {
                    if (value.GetType().GetInterface("IConvertible") != null)
                    {
                        value = value.GetType().FullName == propertyInfo.PropertyType.FullName ? value : Convert.ChangeType(value, propertyInfo.PropertyType);
                        propertyInfo.SetValue(obj, value);
                    }
                }
                catch
                {
                    throw new Exception(string.Format("An error occurred when attempting to set the value of {0} of type {1}", propertyName, obj.ToString()));
                }
            }
        }
    }

Jacob Saylor

Software developer in Kentucky

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: