• .Net 【基础回顾】深浅复制


    摘要

    复制一直是面试喜欢问的问题,这里总结一下

    浅复制与深复制

    • 浅copy:只复制引用,修改后对原来的变量有影响。

    • 深copy:复制引用和引用的对象,修改后对原来的变量没有影响

    =复制

    浅复制

    • 值类型:复制值,修改后对原来的变量没有影响

    • 引用类型:复制引用地址,修改后对原来的变量有影响

    • String: 跟着值类型走

    MemberwiseClone

    浅复制

    Object的实例方法MemberwiseClone实现的是浅复制,注意是protected修饰,只能定义的继承类或者extension实现

    protected Object MemberwiseClone();
    

    深copy实现

    1. 反射

    2. 序列化反序列化,最简单

    3. 实现ICloneable接口Clone方法,手工复制对象的每一个field

    通用实现

    序列化

    
    using System;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace DotnetDemo
    {
        [Serializable]
        public class BaseClone<T>
        {
            public virtual T Clone()
            {
                using (var memoryStream = new MemoryStream())
                {
                    var formatter = new BinaryFormatter();
                    formatter.Serialize(memoryStream, this);
                    memoryStream.Position = 0;
                    return (T)formatter.Deserialize(memoryStream);
                }
            }
        } 
    }
    
    
    

    实现的demo

    注意必须为相关类及类的引用类型加上可序列化标识:[Serializable]

    
    using System;
    
    namespace DotnetDemo
    {
        public class CloneDemo
        {
            public void Test()
            {
                // 值类型
    
                var aa = 11;
                var bb = aa;
                bb = 22;
    
                Console.WriteLine(aa); //11
    
                // string
    
                var cc = "11";
                var dd = cc;
                dd = "22";
    
                Console.WriteLine(cc); //"11"
    
                // 引用类型
    
                var ee = new CloneDemoInfo() { ID = 11, ExtensionInfo = new ExtensionInfo() { Name = "Name" } };
                var ff = ee;
                var gg = ee.ShallowCopy();
               
    
               
    
                ff.ID = 22;
                ff.ExtensionInfo = new ExtensionInfo() { Name = "newName" };
    
                Console.WriteLine(ee.ID); // 22
    
                Console.WriteLine(ee.ExtensionInfo.Name); // newName
    
                var hh = ee.Clone();
    
                hh.ID = 33;
                hh.ExtensionInfo = new ExtensionInfo() { Name = "CloneName" };
    
                Console.WriteLine(ee.ID); // 22
    
                Console.WriteLine(ee.ExtensionInfo.Name); // newName
    
            }
        }
    
        [Serializable]
        public class ExtensionInfo
        {
            public string Name { get; set; }
        }
    
        [Serializable]
        public class CloneDemoInfo : BaseClone<CloneDemoInfo>
        {
    
            public int ID { get; set; } //值类型
    
            public ExtensionInfo ExtensionInfo { get; set; } //引用类型
    
            /// <summary>
            /// 浅复制
            /// </summary>
            /// <returns></returns>
            public CloneDemoInfo ShallowCopy()
            {
                return (CloneDemoInfo)this.MemberwiseClone();
            }
    
    
        }
    }
    
    
  • 相关阅读:
    关于JQ的$.deferred()
    JS去掉数组的重复项
    JS中iframe相关的window.self,window.parent,window.top
    JQ的live(),on(),deletage(),bind()几个的区别
    个人对闭包的理解
    ajax 代码
    Don't use runAllManagedModulesForAllRequests="true" when getting your MVC routing to work
    SQL语句收集
    性能速度
    ADO.NET(SqlConnection、SqlCommand、SqlDataAdapter、SqlTransaction、SqlParameter、DataSet)
  • 原文地址:https://www.cnblogs.com/thomerson/p/11494483.html
Copyright © 2020-2023  润新知