C#学习——Clone浅学:浅拷贝

      继承ICloneable接口后,内部克隆实现经常用到 MemberwiseClone() 来实现。书上看到解释,说这是浅克隆,对于值类型,正常执行克隆操作,而对于引用类型,则是将引用进行了克隆。在新的对象中仅保存了原对象的一个引用,带来的副作用就是,新对象中修改了值,新对象中的值也随着变化。

      根据这种解释自己写了实例进行尝试:如下声明一个People类,包括三个属性:int、string、enum三种类型。

View Code
 1  internal class People : ICloneable
 2     {
 3         public int Age { get; set; }
 4         public string Name { get; set; }
 5         public Sex Sex { get; set; }
 6 
 7         public object Clone()
 8         {
 9             return MemberwiseClone();
10         }
11 
12         public override string ToString()
13         {
14             return String.Format("Name: {0}, Age: {1}, Sex: {2}, HashCode: {3}.",Name,Age,Sex,GetHashCode());
15         }
16     }

      然后实现对象的克隆,并在修改新对象后输出

View Code
 private static void Main(string[] args)
        {
            var people1 = new People {Age = 1, Name = "Tom", Sex = Sex.Male};
            Console.WriteLine(people1.ToString());
            var people2 = (People)people1.Clone();
            people2.Age = 2;
            people2.Name = "Jim";
            people2.Sex=Sex.Female;
            Console.WriteLine(people1.ToString());
            Console.WriteLine(people2.ToString());
          }

  输出如图:

     表示新的克隆对象与源对象并不是同一个引用,内部的string、enum等类型也互不影响,是两个不同的内存区域。书中这部分说法是错误的。

     对于复杂的引用类型,则是另外的情形。新建类型测试:

View Code
 1 class MyClass:ICloneable
 2     {
 3         public int ID { get; set; }
 4 
 5         public People Teacher { get; set; }
 6 
 7         public object Clone()
 8         {
 9             return MemberwiseClone();
10         }
11 
12         public override string ToString()
13         {
14             return String.Format("ID:{4} Name: {0}, Age: {1}, Sex: {2}, HashCode: {3}, Teacher HashCode:{5}.", Teacher.Name, Teacher.Age, Teacher.Sex, GetHashCode(),ID,Teacher.GetHashCode());
15         }
16     }

  实现对象的克隆,并在修改新对象后输出

View Code
1  var class1 = new MyClass { ID = 1, Teacher = new People { Age = 1, Name = "Tom", Sex = Sex.Male } };
2             Console.WriteLine(class1.ToString());
3             var class2 = (MyClass)class1.Clone();
4             class2.ID = 2;
5             class2.Teacher.Age = 2;
6             class2.Teacher.Name = "Jim";
7             class2.Teacher.Sex = Sex.Female;
8             Console.WriteLine(class1.ToString());
9             Console.WriteLine(class2.ToString());

  此次输出结果如图:

  结果表示,对象的克隆生成了一个新的不同的类型,值类型在两个对象中存在两份,修改互不影响。而引用类型则只存在一份实例,Teacher HashCode相同,修改一个对象中的引用属性,会影响到另一个对象。这就是所谓的“浅拷贝”。

 

 

posted @ 2013-03-19 00:00  菜鸟撞飞机  阅读(207)  评论(0编辑  收藏  举报