123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- using CyberX8_Core;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using System.Threading.Tasks;
- namespace MECF.Framework.Common.Utilities
- {
- public class PropertyUtil
- {
- public static object Clone(object source)
- {
- Type type = source.GetType();
- object target = System.Activator.CreateInstance(type);
- BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;
- PropertyInfo[] propertyInfos = type.GetProperties(bindingFlags);
- foreach (PropertyInfo property in propertyInfos)
- {
- if (!property.CanWrite) continue;
- //check whether property type is value type, enum or string type
- if (property.PropertyType.IsPrimitive || property.PropertyType.IsEnum || property.PropertyType == typeof(string))
- {
- property.SetValue(target, property.GetValue(source, null), null);
- }
- else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
- {
- //Include List and Dictionary and......
- if (property.PropertyType.IsGenericType)
- {
- var cloneObj = Activator.CreateInstance(property.PropertyType);
- var addMethod = property.PropertyType.GetMethod("Add", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
- Debug.Assert(null != addMethod);
- var currentValues = property.GetValue(source, null) as IEnumerable;
- if (currentValues == null)
- {
- property.SetValue(target, null, null);
- }
- else
- {
- if (cloneObj is IDictionary)
- {
- cloneObj = cloneObj as IDictionary;
- foreach (var currentValue in currentValues)
- {
- var propInfoKey = currentValue.GetType().GetProperty("Key");
- var propInfoValue = currentValue.GetType().GetProperty("Value");
- if (propInfoKey != null && propInfoValue != null)
- {
- var keyValue = propInfoKey.GetValue(currentValue, null);
- var valueValue = propInfoValue.GetValue(currentValue, null);
- object finalKeyValue, finalValueValue;
- //Get finalKeyValue
- var currentKeyType = keyValue.GetType();
- if (currentKeyType.IsPrimitive || currentKeyType.IsEnum || currentKeyType == typeof(string))
- {
- finalKeyValue = keyValue;
- }
- else
- {
- //Reference type
- var copyObj = Clone(keyValue);
- finalKeyValue = copyObj;
- }
- //Get finalValueValue
- var currentValueType = valueValue.GetType();
- if (currentValueType.IsPrimitive || currentValueType.IsEnum || currentValueType == typeof(string))
- {
- finalValueValue = valueValue;
- }
- else
- {
- //Reference type
- var copyObj = Clone(valueValue);
- finalValueValue = copyObj;
- }
- addMethod.Invoke(cloneObj, new[] { finalKeyValue, finalValueValue });
- }
- }
- property.SetValue(target, cloneObj, null);
- }
- //Common IList type
- else
- {
- foreach (var currentValue in currentValues)
- {
- var currentType = currentValue.GetType();
- if (currentType.IsPrimitive || currentType.IsEnum || currentType == typeof(string))
- {
- addMethod.Invoke(cloneObj, new[] { currentValue });
- }
- else
- {
- //Reference type
- var copyObj = Clone(currentValue);
- addMethod.Invoke(cloneObj, new[] { copyObj });
- }
- }
- property.SetValue(target, cloneObj, null);
- }
- }
- }
- //Array type
- else
- {
- var currentValues = property.GetValue(source, null) as Array;
- if (null == currentValues)
- {
- property.SetValue(target, null, null);
- }
- else
- {
- var cloneObj = Activator.CreateInstance(property.PropertyType, currentValues.Length) as Array;
- var arrayList = new ArrayList();
- for (var i = 0; i < currentValues.Length; i++)
- {
- var currentType = currentValues.GetValue(i).GetType();
- if (currentType.IsPrimitive || currentType.IsEnum || currentType == typeof(string))
- {
- arrayList.Add(currentValues.GetValue(i));
- }
- else
- {
- //Reference type
- var copyObj = Clone(currentValues.GetValue(i));
- arrayList.Add(copyObj);
- }
- }
- arrayList.CopyTo(cloneObj, 0);
- property.SetValue(target, cloneObj, null);
- }
- }
- }
- else if (property.PropertyType.IsClass)
- {
- object inner = property.GetValue(source, null);
- property.SetValue(target, Clone(inner), null);
- }
- else
- {
- property.SetValue(target, property.GetValue(source, null), null);
- }
- }
- return target;
- }
- }
- }
|