C # reference type deep copy helper

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
    {
        // use a dictionary to store the number of reflections each object to avoid the reflection code recursive loop 
        static  Readonly the Dictionary <the Type, int > = TypereflectionCountDic new new the Dictionary <the Type, int > ();
         // static Object _deepCopyDemoClasstypeRef = null;
         // using reflected achieve deep copy 
        public  static T DeepCopyWithReflection <T> (T obj)
        {
            Type type = obj.GetType ();
             // if the type is a string or a value directly returns 
            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 the string or value type directly returns 
            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());
                    }
                }
            }

            // For the object class type reflection recording start times 
            int reflectionCount = the 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];
        }

        // use XML serialization and deserialization achieve 
        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;
        }

        // the binary sequence to achieve and deserialization (useful for pro-test) 
        public  static T DeepCopyWithBinarySerialize <T> (T obj)
        {
            object retval;
            using (MemoryStream ms = new MemoryStream())
            {
                BF the BinaryFormatter = new new the BinaryFormatter ();
                 // serialized stream 
                bf.Serialize (ms, obj);
                ms.Seek ( 0 , SeekOrigin.Begin);
                 // deserialized into objects 
                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;
        // }
         // expression tree implementation
         // .... 
        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 all-trans (Tin Tin)
            {
                return cache(tIn);
            }
        }
    }
}

 

Guess you like

Origin www.cnblogs.com/zhang1f/p/11104444.html