• C#对象复制 ICloneable


    .net framework中,提供了ICloneable接口来对对象进行克隆。当然,你也可以不去实现ICloneable接口而直接自己定义一个Clone()方法,当然,还是推荐实现ICloneable接口。

    具体实现方法

    using UnityEngine;
    using System.Collections;
    using System;  
    using System.IO;  
    using System.Runtime.Serialization;  
    using System.Runtime.Serialization.Formatters.Binary;  
    
    [Serializable]  
    public class Job  
    {  
        public int id;
        public string JobName { get; set; }  
        public override string ToString()  
        {  
            return this.JobName;  
        } 
        public int ID 
        {
            get { return id;}
            set { id = value;}
        } 
    }
    
    [Serializable]  
    public class Person:ICloneable   
    {  
        public int Age { get; set; }  //值类型字段  
        public string Name { get; set; }  //字符串  
        public Job Job { get; set; }  //引用类型字段  
    
        //深拷贝  
        public Person DeepClone()  
        {  
            using (Stream objectStream = new MemoryStream())  
            {  
                IFormatter formatter = new BinaryFormatter();  
                formatter.Serialize(objectStream,this);  
                objectStream.Seek(0, SeekOrigin.Begin);  
                return formatter.Deserialize(objectStream) as Person;  
            }  
        }  
    
        public object Clone()  
        {  
            return this.MemberwiseClone();  //浅拷贝
        }  
    
        //浅拷贝  
        public Person ShallowClone()  
        {  
            return this.Clone() as Person;  
        }  
    }  

    测试案例:

    using UnityEngine;
    using System.Collections;
    
    //测试C# 类拷贝
    public class ClassCloneTest : MonoBehaviour {
    
        // Use this for initialization
        void Start () 
        {
            Person p = new Person() { Name = "test0001", Age = 20,Job = new Job(){JobName="Coder",ID = 100022 } };  
            
            string Str = "";
            
            Str = string.Format("修改前:p.Name={0},p.Age={1},p.Job.JobName={2}", p.Name, p.Age, p.Job.JobName); 
    
            
            Person p1 = p.ShallowClone();  
            Person p2 = p.DeepClone();  
    
            
            Debug.Log(Str); 
            Str = string.Format("修改前:p1.Name={0},p1.Age={1},p1.Job.JobName={2}", p1.Name, p1.Age, p1.Job.JobName); 
            Debug.Log(Str);  
            Str = string.Format("修改前:p2.Name={0},p2.Age={1},p2.Job.JobName={2}", p2.Name, p2.Age, p2.Job.JobName);  
            Debug.Log(Str); 
    
            //修改p的所有字段值 
            Debug.Log("修改P1的值:   "); 
            p1.Name = "test000222222";  
            p1.Age = 100;  
            p1.Job.JobName = "Manager";  
            p1.Job.ID = 1111;  
    
            Str = string.Format("修改后:p.Name={0},p.Age={1},p.Job.JobName={2}", p.Name, p.Age, p.Job.JobName);  
            Debug.Log(Str); 
            Str = string.Format("修改后:p1.Name={0},p1.Age={1},p1.Job.JobName={2}", p1.Name, p1.Age, p1.Job.JobName);  
            Debug.Log(Str); 
            Str = string.Format("修改后:p2.Name={0},p2.Age={1},p2.Job.JobName={2}", p2.Name, p2.Age, p2.Job.JobName); 
            Debug.Log(Str); 
        }
    }

    结果输出:

      

    结论:

      这个结果可以看出,浅表副本和原始副本并不是一个对象,但是,浅表副本复制了原始对象的值类型和string类型,但是数组只复制了引用。

          这个现象很有趣,按照MSDN的定义:“MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。

          如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。”,

      但是,在实际上,string应该也是引用类型,但是,浅表副本却复制了这个值。

      无论是浅拷贝与深拷贝,C#都将源对象中的所有字段复制到新的对象中。不过,对于值类型字段,引用类型字段以及字符串类型字段的处理,两种拷贝方式存在一定的区别(见下表)。

      

    参考: http://visionsky.blog.51cto.com/blog/733317/237917

        http://blog.csdn.net/yl2isoft/article/details/12200513

  • 相关阅读:
    基于visual Studio2013解决面试题之1307二分查找
    基于visual Studio2013解决面试题之1306奇偶位数交换
    基于visual Studio2013解决面试题之1305字符串所有子集
    cocos2d-x游戏开发系列教程-坦克大战游戏之虚拟手柄控制坦克移动
    cocos2d-x游戏开发系列教程-坦克大战游戏之虚拟手柄的显示
    cocos2d-x游戏开发系列教程-坦克大战游戏之坦克的显示
    基于visual Studio2013解决面试题之1204大数组查找
    6.6 判断字符串是不是字母类型的
    6.4 从字符串中删除不需要的字符
    6.3 计算字符在字符串中出现的次数
  • 原文地址:https://www.cnblogs.com/beeasy/p/6069255.html
Copyright © 2020-2023  润新知