MSDN Library
信息
您所需的主题如下所示。但此主题未包含在此库中。

Object.MemberwiseClone 方法

2013/12/13

创建当前 Object 的浅表副本。

Namespace:  System
程序集:  mscorlib(位于 mscorlib.dll 中)

protected Object MemberwiseClone()

返回值

类型: System.Object
当前 Object 的浅表副本。

MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。

例如,考虑一个名为 X 的对象,该对象引用对象 A 和 B。对象 B 又引用对象 C。X 的浅表副本创建一个新对象 X2,该对象也引用对象 A 和 B。与此相对照,X 的深层副本创建一个新对象 X2,该对象引用新对象 A2 和 B2,它们分别是 A 和 B 的副本。B2 又引用新对象 C2,C2 是 C 的副本。该示例阐释了浅层和深层复制操作之间的区别。

有很多方法可以实现深层复制操作,前提是浅表复制操作由 MemberwiseClone 方法执行但不符合您的需求。这些要求包括:

  • 调用要复制的对象的类构造函数以创建含有从第一个对象中提出的属性值的第二个对象。这假定对象的值完全由类构造函数定义。

  • 调用 MemberwiseClone 方法创建的对象的浅表副本,然后将指定新的对象,其值均相同,原始对象的任何属性或字段的值是引用类型。该示例中的 DeepCopy 方法阐释了这种方法。

  • 序列化要深层复制的对象,然后将序列化的数据还原到另一个对象变量。

  • 使用带递归的反射执行的深层复制操作。

下面的示例演示 MemberwiseClone 方法。它定义了 ShallowCopy 方法,该方法通过调用 MemberwiseClone 方法来在 Person 对象上执行浅表复制操作。它还定义了在 Person 对象上执行深层复制操作的 DeepCopy 方法。


using System;

public class IdInfo
{
   public int IdNumber;

   public IdInfo(int IdNumber)
   {
      this.IdNumber = IdNumber;
   }
}

public class Person
{
   public int Age;
   public string Name;
   public IdInfo IdInfo;

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

   public Person DeepCopy()
   {
      Person other = (Person)this.MemberwiseClone();
      other.IdInfo = new IdInfo(this.IdInfo.IdNumber);
      return other;
   }
}

public class Example
{
   public static void Demo(System.Windows.Controls.TextBlock outputBlock)
   {
      // Create an instance of Person and assign values to its fields.
      Person p1 = new Person();
      p1.Age = 42;
      p1.Name = "Sam";
      p1.IdInfo = new IdInfo(6565);

      // Perform a shallow copy of p1 and assign it to p2.
      Person p2 = (Person)p1.ShallowCopy();

      // Display values of p1, p2
      outputBlock.Text += "Original values of p1 and p2:" + "\n";
      outputBlock.Text += "   p1 instance values: " + "\n";
      DisplayValues(outputBlock, p1);
      outputBlock.Text += "   p2 instance values:" + "\n";
      DisplayValues(outputBlock, p2);

      // Change the value of p1 properties and display the values of p1 and p2.
      p1.Age = 32;
      p1.Name = "Frank";
      p1.IdInfo.IdNumber = 7878;
      outputBlock.Text += "\nValues of p1 and p2 after changes to p1:" + "\n";
      outputBlock.Text += "   p1 instance values: " + "\n";
      DisplayValues(outputBlock, p1);
      outputBlock.Text += "   p2 instance values:" + "\n";
      DisplayValues(outputBlock, p2);

      // Make a deep copy of p1 and assign it to p3.
      Person p3 = p1.DeepCopy();
      // Change the members of the p1 class to new values to show the deep copy.
      p1.Name = "George";
      p1.Age = 39;
      p1.IdInfo.IdNumber = 8641;
      outputBlock.Text += "\nValues of p1 and p3 after changes to p1:" + "\n";
      outputBlock.Text += "   p1 instance values: " + "\n";
      DisplayValues(outputBlock, p1);
      outputBlock.Text += "   p3 instance values:" + "\n";
      DisplayValues(outputBlock, p3);
   }

   public static void DisplayValues(System.Windows.Controls.TextBlock outputBlock, Person p)
   {
      outputBlock.Text += String.Format("      Name: {0:s}, Age: {1:d}", p.Name, p.Age) + "\n";
      outputBlock.Text += String.Format("      Value: {0:d}", p.IdInfo.IdNumber) + "\n";
   }
}
// The example displays the following output:
//       Original values of p1 and p2:
//          p1 instance values:
//             Name: Sam, Age: 42
//             Value: 6565
//          p2 instance values:
//             Name: Sam, Age: 42
//             Value: 6565
//       
//       Values of p1 and p2 after changes to p1:
//          p1 instance values:
//             Name: Frank, Age: 32
//             Value: 7878
//          p2 instance values:
//             Name: Sam, Age: 42
//             Value: 7878
//       
//       Values of p1 and p3 after changes to p1:
//          p1 instance values:
//             Name: George, Age: 39
//             Value: 8641
//          p3 instance values:
//             Name: Frank, Age: 32
//             Value: 7878


在此示例中,Person.IdInfo 属性返回 IdInfo 对象。如示例输出所示,调用 MemberwiseClone 方法克隆 Person 对象时,克隆的 Person 对象是原始对象的独立副本,但它们共享相同的 Person.IdInfo 对象引用。其结果是,修改克隆的 Person.IdInfo 属性将更改原始对象的 Person.IdInfo 属性。另一方面,执行深层复制操作时,克隆出来的 Person 对象,包括其 Person.IdInfo 属性,都可以修改,而且不会影响原始对象。

Windows Phone OS

受以下版本支持: 8.0, 7.1, 7.0

Windows Phone

显示:
© 2016 Microsoft