• 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;
            }
        }
  • 相关阅读:
    [LeetCode] 952. Largest Component Size by Common Factor 按公因数计算最大部分大小
    [LeetCode] 951. Flip Equivalent Binary Trees 翻转等价二叉树
    [LeetCode] 950. Reveal Cards In Increasing Order 按递增顺序显示卡牌
    上周热点回顾(7.6-7.12)团队
    上周热点回顾(6.29-7.5)团队
    上周热点回顾(6.22-6.28)团队
    调用博客园 open api 的客户端示例代码团队
    【故障公告】阿里云 RDS 实例 CPU 100% 故障引发全站无法正常访问团队
    上周热点回顾(6.15-6.21)团队
    《证券投资顾问胜任能力考试》考试大纲
  • 原文地址:https://www.cnblogs.com/refuge/p/8449715.html
Copyright © 2020-2023  润新知