C# 引用类型的深度拷贝帮助类

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Xml.Serialization;



namespace CommonSD
{
    public class DeepCopyHelper
    {
        // 用一个字典来存放每个对象的反射次数来避免反射代码的循环递归
        static readonly Dictionary<Type, int> TypereflectionCountDic = new Dictionary<Type, int>();
        //static object _deepCopyDemoClasstypeRef = null;
        // 利用反射实现深拷贝
        public static T DeepCopyWithReflection<T>(T obj)
        {
            Type type = obj.GetType();
            // 如果是字符串或值类型则直接返回
            if (obj is string || type.IsValueType) return obj;
            if (type.IsArray)
            {
                if (type.FullName != null)
                {
                    Type elementType = Type.GetType(type.FullName.Replace("[]", string.Empty));
                    var array = obj as Array;
                    if (array != null)
                    {
                        Array copied = Array.CreateInstance(elementType ?? throw new InvalidOperationException(), array.Length);
                        for (int i = 0; i < array.Length; i++)
                        {
                            copied.SetValue(DeepCopyWithReflection(array.GetValue(i)), i);
                        }
                        return (T) Convert.ChangeType(copied, obj.GetType());
                    }
                }
            }

            object retval = Activator.CreateInstance(obj.GetType());

            PropertyInfo[] properties = obj.GetType().GetProperties(
                BindingFlags.Public | BindingFlags.NonPublic
                | BindingFlags.Instance | BindingFlags.Static);
            foreach (var property in properties)
            {
                var propertyValue = property.GetValue(obj, null);
                if (propertyValue == null)
                    continue;
                property.SetValue(retval, DeepCopyWithReflection(propertyValue), null);
            }
            return (T) retval;
        }



        public static T DeepCopyWithReflection_Second<T>(T obj)
        {
            Type type = obj.GetType();

            // 如果是字符串或值类型则直接返回
            if (obj is string || type.IsValueType) return obj;
            if (type.IsArray)
            {
                if (type.FullName != null)
                {
                    Type elementType = Type.GetType(type.FullName.Replace("[]", string.Empty));
                    var array = obj as Array;
                    if (array != null)
                    {
                        Array copied = Array.CreateInstance(elementType ?? throw new InvalidOperationException(), array.Length);
                        for (int i = 0; i < array.Length; i++)
                        {
                            copied.SetValue(DeepCopyWithReflection_Second(array.GetValue(i)), i);
                        }
                        return (T) Convert.ChangeType(copied, obj.GetType());
                    }
                }
            }

            // 对于类类型开始记录对象反射的次数
            int reflectionCount = Add(TypereflectionCountDic, obj.GetType());
            if (reflectionCount > 1)
                return obj;

            object retval = Activator.CreateInstance(obj.GetType());

            PropertyInfo[] properties = obj.GetType().GetProperties(
                BindingFlags.Public | BindingFlags.NonPublic
                | BindingFlags.Instance | BindingFlags.Static);
            foreach (var property in properties)
            {
                var propertyValue = property.GetValue(obj, null);
                if (propertyValue == null)
                    continue;
                property.SetValue(retval, DeepCopyWithReflection_Second(propertyValue), null);
            }
            return (T) retval;
        }



        //public static T DeepCopyWithReflection_Third<T>(T obj)
        //{
        //    Type type = obj.GetType();
        //    // 如果是字符串或值类型则直接返回
        //    if (obj is string || type.IsValueType) return obj;
        //    if (type.IsArray)
        //    {
        //        Type elementType = Type.GetType(type.FullName.Replace("[]", string.Empty));
        //        var array = obj as Array;
        //        Array copied = Array.CreateInstance(elementType, array.Length);
        //        for (int i = 0; i < array.Length; i++)
        //        {
        //            copied.SetValue(DeepCopyWithReflection_Second(array.GetValue(i)), i);
        //        }
        //        return (T) Convert.ChangeType(copied, obj.GetType());
        //    }
        //    int reflectionCount = Add(typereflectionCountDic, obj.GetType());
        //    if (reflectionCount > 1 && obj.GetType() == typeof(DeepCopyDemoClass))
        //        return (T) DeepCopyDemoClasstypeRef; // 返回deepCopyClassB对象
        //    object retval = Activator.CreateInstance(obj.GetType());
        //    if (retval.GetType() == typeof(DeepCopyDemoClass))
        //        DeepCopyDemoClasstypeRef = retval; // 保存一开始创建的DeepCopyDemoClass对象
        //    PropertyInfo[] properties = obj.GetType().GetProperties(
        //        BindingFlags.Public | BindingFlags.NonPublic
        //        | BindingFlags.Instance | BindingFlags.Static);
        //    foreach (var property in properties)
        //    {
        //        var propertyValue = property.GetValue(obj, null);
        //        if (propertyValue == null)
        //            continue;
        //        property.SetValue(retval, DeepCopyWithReflection_Third(propertyValue), null);
        //    }
        //    return (T) retval;
        //}

        //private static T SetArrayObject<T>(T arrayObj)
        //{
        //    Type elementType = Type.GetType(arrayObj.GetType().FullName.Replace("[]", string.Empty));
        //    var array = arrayObj as Array;
        //    Array copied = Array.CreateInstance(elementType, array.Length);
        //    for (int i = 0; i < array.Length; i++)
        //    {
        //        copied.SetValue(DeepCopyWithReflection_Third(array.GetValue(i)), i);
        //    }
        //    return (T) Convert.ChangeType(copied, arrayObj.GetType());
        //}

        private static int Add(Dictionary<Type, int> dict, Type key)
        {
            if (key == typeof(string) || key.IsValueType) return 0;
            if (!dict.ContainsKey(key))
            {
                dict.Add(key, 1);
                return dict[key];
            }
            dict[key] += 1;
            return dict[key];
        }

        // 利用XML序列化和反序列化实现
        public static T DeepCopyWithXmlSerializer<T>(T obj)
        {
            object retval;
            using (MemoryStream ms = new MemoryStream())
            {
                XmlSerializer xml = new XmlSerializer(typeof(T));
                xml.Serialize(ms, obj);
                ms.Seek(0, SeekOrigin.Begin);
                retval = xml.Deserialize(ms);
                ms.Close();
            }
            return (T) retval;
        }

        // 利用二进制序列化和反序列实现(亲测有用)
        public static T DeepCopyWithBinarySerialize<T>(T obj)
        {
            object retval;
            using (MemoryStream ms = new MemoryStream())
            {
                BinaryFormatter bf = new BinaryFormatter();
                // 序列化成流
                bf.Serialize(ms, obj);
                ms.Seek(0, SeekOrigin.Begin);
                // 反序列化成对象
                retval = bf.Deserialize(ms);
                ms.Close();
            }
            return (T) retval;
        }

        // 利用DataContractSerializer序列化和反序列化实现
        //public static T DeepCopy<T>(T obj)
        //{
        //    object retval;
        //    using (MemoryStream ms = new MemoryStream())
        //    {
        //        DataContractSerializer ser = new DataContractSerializer(typeof(T));
        //        ser.WriteObject(ms, obj);
        //        ms.Seek(0, SeekOrigin.Begin);
        //        retval = ser.ReadObject(ms);
        //        ms.Close();
        //    }
        //    return (T) retval;
        //}
        // 表达式树实现
        // ....
        public static class TransExpV2<TIn, TOut>
        {
            private static readonly Func<TIn, TOut> cache = GetFunc();
            private static Func<TIn, TOut> GetFunc()
            {
                ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");
                List<MemberBinding> memberBindingList = new List<MemberBinding>();

                foreach (var item in typeof(TOut).GetProperties())
                {
                    if (!item.CanWrite)
                        continue;

                    MemberExpression property =
                        Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name));

                    MemberBinding memberBinding = Expression.Bind(item, property);
                    memberBindingList.Add(memberBinding);
                }  
                MemberInitExpression memberInitExpression =
                    Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());

                Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression,
                    new ParameterExpression[] {parameterExpression});
                return lambda.Compile();
            }

            public static TOut Trans(TIn tIn)
            {
                return cache(tIn);
            }
        }
    }
}

 

C# 引用类型的深度拷贝帮助类

上一篇:C# log4net记录日志


下一篇:百度SMS发送短信C#