C#中浅表副本与深表副本

时间:2022-08-30 17:37:36

原文链接:http://club.topsage.com/thread-2457830-1-1.html

这里讨论的浅表副本与深表副本主要是针对C#的类来说的,我们知道C#的类都是引用类型的,然而类的字段则有可能是值类型和引用类型的。


个人认为浅表副本与深表副本就区分于此。假设我们现在有一个class叫做MyCopyableClass,里面包含有一个值类型string name,和一个引用类型Info information(Info是一个class)。该类里我们生成两个方法ShallowCopy和DeepCopy来分别实现浅表副本和深表副本

1.利用ShallowCopy方法实现浅表副本

那么该方法只需一行代码 return (MyCopyableClass)this.MemberwiseClone();即可实现浅表副本。因为这里MyCopyableClass字段既有值类型也有引用类型。那么对于值类型,副本将在新的内存块中复制值类型的值;而对于引用类型,副本则将同样引用原先的引用类型。也就是说,如果原先的MyCopyableClass字段中的值发生变化,副本字段中的值不发生变化;而如果字段中的引用对象发生变化,则副本中的引用对象也发生变化。

2.利用DeepCopy方法实现深表副本

深表副本主要是针对MyCopyableClass字段里的引用类型的,这样子如果当原先的MyCopyableClass字段中的引用发生变化,然而副本却不发生任何的变化。

相应的例子代码如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Ch10Ex4
{
    class Info
    {
        private int idNumber;

        public Info(int idNumber)
        {
            this.idNumber = idNumber;
        }

        public int IdNumber
        {
            get
            {
                return idNumber;
            }
            set
            {
                idNumber = value;
            }
        }
    }
    class MyCopyableClass
    {

        private Info information;
        private string name;

        public Info Information
        {
            get
            {
                return information;
            }
            set
            {
                information = value;
            }
        }

        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }

        public MyCopyableClass ShallowCopy()
        {
            return (MyCopyableClass)this.MemberwiseClone();
        }

        public MyCopyableClass DeepCopy()
        {
            MyCopyableClass other = (MyCopyableClass)this.MemberwiseClone();
            other.information = new Info(this.information.IdNumber);
            return other;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyCopyableClass person = new MyCopyableClass();
            person.Name = "Huachi";
            person.Information = new Info(442);

            MyCopyableClass shallow = person.ShallowCopy();
            Display(person);
            Display(shallow);

            person.Name = "Woo";
            person.Information.IdNumber = 42;
            Display(person);
            Display(shallow);

            MyCopyableClass deep = person.DeepCopy();
            person.Name = "4T-Shirt";
            person.Information.IdNumber = 1;
            Display(person);
            Display(deep);
        }
        static void Display(MyCopyableClass person)
        {
            Console.WriteLine("My name is {0} and idnumber is {1}", person.Name, person.Information.IdNumber);
        }
    }
}