zoukankan      html  css  js  c++  java
  • c# 几种深拷贝方式的比较

        public static class Tools
        {
            //利用 BinaryFormatter 实现深拷贝
            public static T DeepCopyByBinary<T>(this T obj)
            {
                T t = default(T);
                IFormatter formatter = new BinaryFormatter();
                using (MemoryStream ms = new MemoryStream())
                {
                    formatter.Serialize(ms, obj);
                    ms.Seek(0, SeekOrigin.Begin);
                    t = (T)formatter.Deserialize(ms);
                }
                return t;
            }
    
            //利用 XmlSerializer 实现深拷贝
            public static T DeepCopyByXml<T>(this T obj)
            {
                T t = default(T);
                XmlSerializer xmlserialize = new XmlSerializer(typeof(T));
                using (MemoryStream ms = new MemoryStream())
                {
                    xmlserialize.Serialize(ms, obj);
                    ms.Seek(0, SeekOrigin.Begin);
                    t = (T)xmlserialize.Deserialize(ms);
                }
                return t;
            }
    
            //利用反射实现深拷贝
            public static T DeepCopyByReflection<T>(this T tSource)
            {
                T tResult = Activator.CreateInstance<T>();
                Type sourceType = typeof(T);
                Type resultType = typeof(T);
                var sourcePros = sourceType.GetProperties();
                foreach (var pro in sourcePros)
                {
                    var sourceProValue = pro.GetValue(tSource);
                    var resultPro = resultType.GetProperty(pro.Name);
                    resultPro.SetValue(tResult, sourceProValue);
                }
                return tResult;
            }
        }
                Person p1 = new Person { Id = 1, Name = "wjire" };
                Stopwatch sw1 = new Stopwatch();
                sw1.Start();
                for (int i = 0; i < 100000; i++)
                {
                    Person p2 = p1.DeepCopyByBinary();
                }
                sw1.Stop();
                Console.WriteLine($"DeepCopyByBinary 共耗时 {sw1.ElapsedMilliseconds} 毫秒");
    
    
    
                Stopwatch sw2 = new Stopwatch();
                sw2.Start();
                for (int i = 0; i < 100000; i++)
                {
                    Person p2 = p1.DeepCopyByXml();
                }
                sw2.Stop();
                Console.WriteLine($"DeepCopyByXml 共耗时 {sw2.ElapsedMilliseconds} 毫秒");
    
    
                Stopwatch sw3 = new Stopwatch();
                sw3.Start();
                for (int i = 0; i < 100000; i++)
                {
                    Person p2 = p1.DeepCopyByReflection();
                }
                sw3.Stop();
                Console.WriteLine($"DeepCopyByReflection 共耗时 {sw3.ElapsedMilliseconds} 毫秒");
    
    
                //利用 json.net 实现深拷贝
                Stopwatch sw4 = new Stopwatch();
                sw4.Start();
                for (int i = 0; i < 100000; i++)
                {
                    Person p2 = JsonConvert.DeserializeObject<Person>(JsonConvert.SerializeObject(p1));
                }
                sw4.Stop();
                Console.WriteLine($"Newtonsoft.Json 共耗时 {sw4.ElapsedMilliseconds} 毫秒");

    运行结果:

    反射最快!!

        class Program
        {
            static void Main(string[] args)
            {
                Person p1 = new Person(123)
                {
                    Id = 1,
                    Age = 33,
                    Name = "wjire"
                };
    
                Expression<Func<Person, Person>> exp1 = p => new Person(333) { Id = p.Id, Name = p.Name, Age = p.Age };
                var func1 = exp1.Compile();
                Person p23 = func1(p1);
                Console.WriteLine(p23.Id);
    
    
    
                Console.WriteLine("*****************************");
                ParameterExpression parameterExpression = Expression.Parameter(p1.GetType(), "p"); // 创造了 lambda表达式中的入参: p
                Console.WriteLine(parameterExpression);
    
                List<MemberBinding> memberBindingList = new List<MemberBinding>();
                foreach (PropertyInfo pro in p1.GetType().GetProperties())
                {
                    if (!pro.CanWrite)
                    {
                        continue;
                    }
                    MemberExpression property = Expression.Property(parameterExpression, pro.Name);
                    Console.WriteLine(property);// p.Id,p.Name,p.Age
    
                    MemberBinding memberBinding = Expression.Bind(pro, property);
                    Console.WriteLine(memberBinding);// p=p.Id,p=p.Name,p=p.Age
    
                    memberBindingList.Add(memberBinding);
                }
    
                var rr = Expression.New(p1.GetType().GetConstructor(new Type[] { typeof(int) }), Expression.Constant(default(int)));
    
                MemberInitExpression initExpression = Expression.MemberInit(rr, memberBindingList);
                Console.WriteLine(initExpression);// new Person { Id = p.Id, Name = p.Name, Age = p.Age }
    
                Expression<Func<Person, Person>> exp = Expression.Lambda<Func<Person, Person>>(initExpression, parameterExpression);
                Console.WriteLine(exp);// p => new Person { Id = p.Id, Name = p.Name, Age = p.Age }
    
                Func<Person, Person> func = exp.Compile();
                Person p2 = func(p1);
    
                Console.WriteLine(p2.Name);
                Console.WriteLine(p2.Id);
                Console.WriteLine(p2.Age);
                Console.ReadKey();
            }
        }
    
        internal class Person
        {
            public int Id { get; set; }
            public string Name { get; set; }
    
            public int Age { get; set; }
    
    
            public Person(int id)
            {
                this.Id = id;
            }
        }
  • 相关阅读:
    前端总结挺全面的
    cmd与bat脚本的使用
    Spring控制反转(IoC)的理解
    C# 中迭代器
    URL 分页并排序
    结合Flash上传文件时显示进度条
    C# 语言特性
    where T:new()
    图片缩放特效
    C# 隐藏窗体 ALT+TAb不可见
  • 原文地址:https://www.cnblogs.com/refuge/p/8449715.html
Copyright © 2011-2022 走看看