using Newtonsoft.Json.Linq;
using System.Collections;
using System.Collections.Generic;
public static void Main()
var p1 = new Person(){ Id = 1, FirstName = "Thanh", Roles = new List<string>(){ "Thanh1" }, Group = new Group(){ Name = "Group1" }, GroupDictionary = new Dictionary<string, Group>() { { "dic1", new Group() { Id = 1, Name = "group1" } }, { "dic2", new Group() { Id = 1, Name = "group2" } } } };
var p2 = new Person() { Id = 1, LastName = "Truong Duc", Roles = new List<string>() { "User" }, Group = new Group() { Id = 1 }, GroupDictionary = new Dictionary<string, Group>() { { "dic3", new Group() { Id = 3, Name = "group3" } } } } ;
MergeObject(p1, p2, out p3, typeof(Person));
Console.WriteLine(JsonConvert.SerializeObject(p3));
Console.WriteLine(((Person)p3).FirstName);
private static void MergeObject(object obj1, object obj2, out object obj, Type type)
Console.WriteLine(JsonConvert.SerializeObject(obj1));
Console.WriteLine(JsonConvert.SerializeObject(obj2));
var properties = type.GetProperties().Where(x=>x.CanWrite).ToList();
Console.WriteLine(JsonConvert.SerializeObject(properties.Select(x=>x.PropertyType.FullName).ToList()));
var objDefault = Activator.CreateInstance(type);
obj = Activator.CreateInstance(type);
foreach (var prop in properties)
var propValueDefault = prop.GetValue(objDefault);
var propValue = prop.GetValue(obj1);
Console.WriteLine(typeof(IEnumerable).IsAssignableFrom(prop.PropertyType));
propValue = prop.GetValue(obj2);
} else if(isDictionary(prop)){
Console.WriteLine("DICTIONARY " + prop.PropertyType);
var propObj2Value = prop.GetValue(obj2) as IDictionary;
((IDictionary)propValue).MergeDictionary(propObj2Value);
else if(isCollection(prop))
Console.WriteLine("class" + prop.PropertyType);
var propObj2Value = prop.GetValue(obj2) as IList;
((IList)propValue).MergeList(propObj2Value);
}else if(isChildClass(prop)){
Console.WriteLine("class" + prop.PropertyType);
var propObj2Value = prop.GetValue(obj2);
if(propObj2Value != null){
MergeObject(propValue, propObj2Value, out propValue, prop.PropertyType);
if(propValue.Equals(propValueDefault))
Console.WriteLine("default: " + propValueDefault);
propValue = prop.GetValue(obj2);
prop.SetValue(obj, propValue);
private static bool isCollection(PropertyInfo propertyInfo)
return propertyInfo.PropertyType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(propertyInfo.PropertyType);
private static bool isDictionary(PropertyInfo propertyInfo)
return propertyInfo.PropertyType.IsGenericType && typeof(IDictionary).IsAssignableFrom(propertyInfo.PropertyType);
private static bool isChildClass(PropertyInfo propertyInfo)
return (propertyInfo.PropertyType.IsClass && !propertyInfo.PropertyType.IsValueType &&
!propertyInfo.PropertyType.IsPrimitive && propertyInfo.PropertyType.FullName != "System.String");
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public List<string> Roles {get;set;}
public Group Group{get;set;}
public Dictionary<string, Group> GroupDictionary {get; set; }
public string Name{ get;set;}
public static class MergeExtensions
public static IDictionary MergeDictionary(this IDictionary propValue, IDictionary propObj2Value)
if (propObj2Value != null)
propValue = propObj2Value;
foreach (var key in propObj2Value.Keys)
if (!(propValue).Contains(key))
(propValue).Add(key, propObj2Value[key]);
public static IList MergeList(this IList propValue, IList propObj2Value)
if (propObj2Value != null)
propValue = propObj2Value;
Console.WriteLine(JsonConvert.SerializeObject(propObj2Value));
Console.WriteLine(JsonConvert.SerializeObject(propValue));
foreach (var item in propObj2Value)
(propValue as IList).Add(item);
Console.WriteLine(JsonConvert.SerializeObject(propValue));
Console.WriteLine("propObj2Value is NULL");