• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > 简单谈谈C#中深拷贝、浅拷贝

简单谈谈C#中深拷贝、浅拷贝

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了简单谈谈对党的认识,简单谈谈入党动机,谈谈360会员等级升级,谈谈天气,谈谈星座等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Object.MemberwiseClone 方法

创建当前 Object 的浅表副本。

protected Object MemberwiseClone()
</div>

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 Main()
  {
    // 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
    Console.WriteLine("Original values of p1 and p2:");
    Console.WriteLine("  p1 instance values: ");
    DisplayValues(p1);
    Console.WriteLine("  p2 instance values:");
    DisplayValues(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;
    Console.WriteLine("\nValues of p1 and p2 after changes to p1:");
    Console.WriteLine("  p1 instance values: ");
    DisplayValues(p1);
    Console.WriteLine("  p2 instance values:");
    DisplayValues(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;
    Console.WriteLine("\nValues of p1 and p3 after changes to p1:");
    Console.WriteLine("  p1 instance values: ");
    DisplayValues(p1);
    Console.WriteLine("  p3 instance values:");
    DisplayValues(p3);
  }
 
  public static void DisplayValues(Person p)
  {
    Console.WriteLine("   Name: {0:s}, Age: {1:d}", p.Name, p.Age);
    Console.WriteLine("   Value: {0:d}", p.IdInfo.IdNumber);
  }
}
// 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
</div>

为了实现深度复制,我们就必须遍历有相互引用的对象构成的图,并需要处理其中的循环引用结构。这无疑是十分复杂的。幸好借助.Net的序列化和反序列化机制,可以十分简单的深度Clone一个对象。

原理很简单,首先将对象序列化到内存流中,此时对象和对象引用的所用对象的状态都被保存到内存中。.Net的序列化机制会自动处理循环引用的情况。然后将内存流中的状态信息反序列化到一个新的对象中。

这样一个对象的深度复制就完成了。在原型设计模式中CLONE技术非常关键。

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
 
namespace CloneDemo
{
  [Serializable]
  class DemoClass
  {
    public int i = 0;
    public int[] iArr = { 1, 2, 3 };
 
    public DemoClass Clone1() //浅CLONE
    {
      return this.MemberwiseClone() as DemoClass;
    }
 
    public DemoClass Clone2() //深clone
    {
      MemoryStream stream = new MemoryStream();
      BinaryFormatter formatter = new BinaryFormatter();
      formatter.Serialize(stream, this);
      stream.Position = 0;
      return formatter.Deserialize(stream) as DemoClass;
    }
  }
 
  class Program
  {
    static void Main(string[] args)
    {
      DemoClass a = new DemoClass();
      a.i = 10;
      a.iArr = new int[] { 8, 9, 10 };
      DemoClass b = a.Clone1();
      DemoClass c = a.Clone2();
 
      // 更改 a 对象的iArr[0], 导致 b 对象的iArr[0] 也发生了变化 而 c不会变化
       a.iArr[0] = 88;
 
      Console.WriteLine("MemberwiseClone");
      Console.WriteLine(b.i);
      foreach (var item in b.iArr)
      {
        Console.WriteLine(item);
      }
 
      Console.WriteLine("Clone2");
      Console.WriteLine(c.i);
      foreach (var item in c.iArr)
      {
        Console.WriteLine(item);
      }
 
      Console.ReadLine();
    }
  }
}
</div>

以上所述就是本文的全部内容了,希望大家能够喜欢。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 简单谈谈C#中深拷贝、浅拷贝

相关文章

  • 2017-05-28C#数据结构之堆栈(Stack)实例详解
  • 2017-05-28C#实现向函数传递不定参数的方法
  • 2017-05-28C# .net实现货币转换示例
  • 2017-05-28不安装excel使用c#创建excel文件
  • 2017-05-28C# 泛型类(函数)的实例化小例子
  • 2017-05-28C#中基于流的XML文件操作笔记
  • 2017-05-28C# 创建,读取,写入XML文件
  • 2017-05-28C#预处理指令之#line,#pragma warning 详细解析
  • 2017-05-28C#实现带进度条的ListView
  • 2017-05-28C# dynamic关键字的使用方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • c#剪切板操作的简单实例
    • C#中string.format用法详解
    • C#装饰器模式(Decorator Pattern)实例教程
    • C#实现图像锐化的方法
    • winfrom 打印表格 字符串的封装实现代码 附源码下载
    • c# DevExpress gridcontrol日期行的显示格式设置
    • C#实现注册码的方法
    • C#编程实现DataTable添加行的方法
    • Winform实现鼠标可穿透的窗体镂空效果
    • 浅谈C# 中的委托和事件

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有