构建可克隆的对象(ICloneable)

时间:2023-01-16 22:14:08

ICloneable接口

  如果想使自己的自定义类型支持向调用方返回自身同样副本的能力,需要实现标准ICloneable接口。

 namespace System
{ public interface ICloneable
{
object Clone();
}
}

浅拷贝

  System.Object定义了一个名为MemberwiseClone()的成员。这个方法用来获取当前对象的一份浅拷贝。

例:

Point.cs
 namespace CloneablePoint
{
// The Point now supports "clone-ability."
public class Point : ICloneable
{
public int X { get; set; }
public int Y { get; set; }
public PointDescription desc = new PointDescription(); public Point( int xPos, int yPos, string petName )
{
X = xPos; Y = yPos;
desc.PetName = petName;
}
public Point( int xPos, int yPos )
{
X = xPos; Y = yPos;
}
public Point() { } // Override Object.ToString().
public override string ToString()
{
return string.Format("X = {0}; Y = {1}; Name = {2};\nID = {3}\n",
X, Y, desc.PetName, desc.PointID);
} // Return a copy of the current object.
// Now we need to adjust for the PointDescription member.
public object Clone()
{
// 这个复制每个Ponit字段成员
Point newPoint = (Point)this.MemberwiseClone();
return newPoint;
}
}
}
PointDescription.cs
 namespace CloneablePoint
{
// This class describes a point.
public class PointDescription
{
public string PetName { get; set; }
public Guid PointID { get; set; } public PointDescription()
{
PetName = "No-name";
PointID = Guid.NewGuid();
}
}
}
Program.cs
 namespace CloneablePoint
{
class Program
{
static void Main( string[] args )
{
Console.WriteLine("***** Fun with Object Cloning *****\n");
Console.WriteLine("Cloned p3 and stored new Point in p4");
Point p3 = new Point(, , "Jane");
Point p4 = (Point)p3.Clone(); Console.WriteLine("Before modification:");
Console.WriteLine("p3: {0}", p3);
Console.WriteLine("p4: {0}", p4);
p4.desc.PetName = "My new Point";
p4.X = ; Console.WriteLine("\nChanged p4.desc.petName and p4.X");
Console.WriteLine("After modification:");
Console.WriteLine("p3: {0}", p3);
Console.WriteLine("p4: {0}", p4);
Console.ReadLine();
}
}
}

构建可克隆的对象(ICloneable)

  请注意,如果Ponint包含任何引用类型成员变量,MemberwiseClone()将这些引用复制到对象中(即浅复制)。如果想要支持真正的深复制,需要在克隆过程中创建任何引用类型变量的新实力。

深拷贝

Point.cs

namespace CloneablePoint
{
public class Point : ICloneable
{
public int X { get; set; }
public int Y { get; set; }
public PointDescription desc = new PointDescription(); public Point( int xPos, int yPos, string petName )
{
X = xPos; Y = yPos;
desc.PetName = petName;
}
public Point( int xPos, int yPos )
{
X = xPos; Y = yPos;
}
public Point() { } public override string ToString()
{
return string.Format("X = {0}; Y = {1}; Name = {2};\nID = {3}\n",
X, Y, desc.PetName, desc.PointID);
} public object Clone()
{
Point newPoint = (Point)this.MemberwiseClone(); PointDescription currentDesc = new PointDescription();
currentDesc.PetName = this.desc.PetName;
newPoint.desc = currentDesc;
return newPoint;
}
}
}

PointDescription.cs

namespace CloneablePoint
{
public class PointDescription
{
public string PetName { get; set; }
public Guid PointID { get; set; } public PointDescription()
{
PetName = "No-name";
PointID = Guid.NewGuid();
}
}
}

Program.cs

namespace CloneablePoint
{
class Program
{
static void Main( string[] args )
{
Console.WriteLine("***** Fun with Object Cloning *****\n");
Console.WriteLine("Cloned p3 and stored new Point in p4");
Point p3 = new Point(, , "Jane");
Point p4 = (Point)p3.Clone(); Console.WriteLine("Before modification:");
Console.WriteLine("p3: {0}", p3);
Console.WriteLine("p4: {0}", p4);
p4.desc.PetName = "My new Point";
p4.X = ; Console.WriteLine("\nChanged p4.desc.petName and p4.X");
Console.WriteLine("After modification:");
Console.WriteLine("p3: {0}", p3);
Console.WriteLine("p4: {0}", p4);
Console.ReadLine();
}
}
}

构建可克隆的对象(ICloneable)