| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 | using PunkHPX8_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;        }    }}
 |