zoukankan      html  css  js  c++  java
  • 由struct 和class 想到的浅度复制和深度复制 c#

    记得c++里面,struct 和class 的唯一不同点是,class的成员默认是private,struct的则默认是public。

    在c#里则不然,struct 默认仍然是private。所以,不禁要问,struct和class有什么区别呢?

    struct 是值类型的,而calss是引用类型的。

    举个例子,

    1 struct Mystruct
    2 {
    3     public int x;
    4 }
    5 
    6 class Myclass
    7 {
    8     public int x;
    9 }

    如果执行以下代码,

    1 Mystruct st1 = new Mystruct();
    2 st1.x = 1;
    3 Mystruct st2 = st1;
    4 st2.x = 2;
    5 
    6 Myclass cs1 = new Myclass();
    7 cs1.x = 1;
    8 Myclass cs2 = cs1;
    9 cs2.x = 2;

    那么修改st2不会影响st1,但是修改cs2则同时也修改了cs1. 这就是值类型和引用类型的区别。cs1 和cs2只是一个指针,他们指向同一个地址。所以修改其中任何一个,他们都会同时被修改。

    既然有值类型和引用类型之分,我们看一看下面这个初学者容易出错的例子:

     1 Myclass [] array = new Myclass[5];
     2 
     3 Myclass tmp = new Myclass();
     4 
     5 for (int i=0;i<5;i++)
     6 
     7 {
     8 
     9     tmp.x = i;
    10 
    11     array[i] = tmp;
    12 
    13 }

    array是不是一个x值等于下标的一个类数组呢?答案是否定的,array数组里面,所有的x都等于4.

    于是对于类复制,引发了有浅度复制和深度复制等概念。

    浅度复制是用过派生于System.Object 的MemberwiseClone()实现的,它可以复制所有值类型,但是对于引用类型,还是只复制了指针。

    深度复制需要实现ICloneable借口的Clone()函数,实现引用类型的复制。

    看一个例子:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace ConsoleTest
     7 {
     8     class Program
     9     {
    10         static void Main(string[] args)
    11         {
    12             CloneExample a = new CloneExample();
    13             a.content = new Content() { con = 1 };
    14             a.x = 2;
    15 
    16             // 浅度复制
    17             CloneExample b = (CloneExample) a.ShallowCopy();
    18             b.content.con = 11;
    19             b.x = 22;
    20             Console.WriteLine("a.content.con = {0}",a.content.con); 
    21             Console.WriteLine("a.x = {0}", a.x);
    22 
    23             //再试一试深度复制
    24             a.content.con = 1;
    25             b = (CloneExample)a.Clone();
    26             b.content.con = 11;
    27             b.x = 22;
    28             Console.WriteLine("a.content.con = {0}", a.content.con);//浅度复制和深度复制的区别体现在,引用类型会不会受影响
    29             Console.WriteLine("a.x = {0}", a.x);
    30 
    31 
    32 
    33             Console.ReadKey();
    34         }
    35 
    36 
    37     }
    38 
    39     class Content {
    40         public int con;
    41     }
    42 
    43     class CloneExample:ICloneable
    44     {
    45         public int x;
    46         public Content content;
    47 
    48         public object ShallowCopy()
    49         {
    50             return this.MemberwiseClone();
    51         }
    52 
    53         public object Clone()
    54         {
    55             CloneExample instance = new CloneExample();
    56             instance.x = this.x;
    57             instance.content = new Content() { con = this.content.con };
    58             return instance;
    59         }
    60     }
    61 }

    使用深度复制,新的变量和就的变量是独立的,互不影响。

    运行结果:

    a.content.con = 11
    a.x = 2
    a.content.con = 1
    a.x = 2

  • 相关阅读:
    java 的 线程池应用和实践
    拦截信息短信息并转发到指定手机
    分享 UC优视 的android程序员面试题
    解释通讯协议中的xml
    设计模式工厂模式
    MongoDB基础教程系列第一篇 进入MongoDB世界
    Docx组件读写Word文档介绍
    [转]Oracle数据库逻辑增量备份之exp/imp
    JSON文件读取
    JAVA综合--如何掌握JDK1.5枚举类型[转]
  • 原文地址:https://www.cnblogs.com/sylvanas2012/p/2588468.html
Copyright © 2011-2022 走看看