首页 > 软件操作教程 > 编程开发 > C#
题目内容

C# 深度复制

题目答案

    通过下面的GetCopy()方法,介绍了如何使用受保护的方法System.Object.MemberwiseClone()进行浅度复制。

public class Cloner 

{

    public int Val;

    public Cloner{int newVal) => Val = newVal; 

    public object GetCopy() => MemberwiseClone();

}

假定有一些引用类型的字段,而不是值类型的字段(例如,对象):

public class Content

{

    public int Val;

}

public class Cloner 

{

    public Content MyContent = new Content();

    public Cloner(int newVal) => MyContent.Val s newVal;

    public object GetCopy() => MemberwiseClone();

}

此时,通过GetCopyO得到的浅度复制包括一个字段,它引用的对象与源对象相同。以下代码使用这个Cloner类来说明浅度复制引用类型的结果:

Cloner mySource = new Cloner(5);

Cloner myTarget = (Cloner)mySource.GetCopy();

WriteLine($"myTarget.MyContent.Val = {myTarget-MyContent.Val}"); 

mySource.MyContent.Val =2;

WriteLine($"myTarget.MyContent.Val = (myTarget .MyContent.Val}");

    第4行把一个值赋给mySource.MyContent.Val,它是源对象中公共字段MyContent的公共字段Val。这也改变了 myTarget.MyContent.Val 的值。这是因为 mySource.MyContent 引用了与 myTargetMyContent 相同的对象实例。上述代码的输出结果如下:

    myTarget.MyContent.Val = 5 

    myTarget.MyContent.Val = 2

为解决这个问题,需要执行深度复制。修改上面的GetCopyO方法就可以进行深度复制,但最好使用.NET Framework的标准方式:实现ICloneable接口,该接口有一个Clone()方法;这个方法不带参数,返回一个object类型的结果,其签名和上面使用的GetCopy()方法相同。

为修改上面的类,可使用下面的深度复制代码:

public class Content 

{

    public int Val;

}

public class Cloner : ICloneable

{

    public Content MyContent = new Content 0;

    public Cloner(int newVal) => MyContent.Val = newVal;

    public object Clone()

    {

        Cloner clonedCloner = new Cloner(MyContent.Val); 

        return clonedCloner;

    }

}

其中使用包含在源Cloner对象中的Content对象(MyContent)的Val字段,创建了一个新对象Cloner。这个字段是一个值类型,所以不需要深度复制。

使用与上面类似的代码来测试浅度复制,但用CloneO替代GetCopy(),得到如下结果:

    myTarget.MyContent.Val = 5 

    myTarget,MyContent.Val = 5

这次包含的对象是独立的。注意有时在比较复杂的对象系统中,调用Clone()是一个递归过程。例如,如果Cloner类的MyContent字段也需要深度复制,就要使用下面的代码:

public class Cloner : ICloneable 

{

    public Content MyContent = new Content();

    ...

    public object Clone()

    {

        Cloner clonedCloner = new Cloner(); 

        clonedCloner.MyContent = MyContent.Clone(); 

        return clonedCloner;

    }

}

这里调用了默认的构造函数,以便简化创建新对象Cloner的语法。为使这段代码能正常工作,还需要在 Content 类上实现 ICloneable 接口。

网友评论(共0条评论)

请自觉遵守互联网相关政策法规,评论内容只代表网友观点!

最新评论

点击加载更多评论>>

软件操作 新人注册送三重礼

已有 22658 名学员学习以下课程通过考试

相关视频试题

最需教育客户端 软件问题一手掌握

去 App Store 免费下载 iOS 客户端