C\#얕 은 복사 와 깊 은 복사 실례 분석

때때로,우 리 는 데이터베이스 에서 데이터 충전 대상 을 읽 거나 하드디스크 에서 파일 충전 대상 을 읽 어야 하지만,이렇게 하 는 데 상대 적 으로 시간 이 걸린다.이때 우 리 는 대상 의 복사 본 을 생각 했다.본 고 는 바로 사례 형식 으로 C\#얕 은 복사 와 깊 은 복사 의 용법 을 분석 했다.구체 적 으로 다음 과 같다.
1.얕 은 복사
1.'얕 은 복사'가 무엇 입 니까?
한 대상 을 대상 으로 복사 할 때 대상 의 값 형식 구성원 에 대해 서 는 그 자 체 를 복사 하고 대상 의 인용 유형 구성원 에 대해 서 는 대상 참조 만 복사 합 니 다.이 인용 은 위탁 관리 더미 의 대상 인 스 턴 스 를 가리 킵 니 다.
2.인용 형식의 클래스 구성원 과 값 형식의 struct 구성원 을 포함 하 는 대상 이 있 습 니 다.
Cinema 는 인용 유형 멤버 Room 과 값 유형 멤버 Film 을 포함 합 니 다.

  public class Room
  {
    public int _maxSeat;
 
    public Room(int maxSeat)
    {
      this._maxSeat = maxSeat;
    }
  }
 
  public struct Film
  {
    public string _name;
 
    public Film(string name)
    {
      this._name = name;
    }
  }
 
  public class Cinema
  {
    public Room _room;
    public Film _film;
 
    public Cinema(Room room, Film film)
    {
      this._room = room;
      this._film = film;
    }
 
    public object Clone()
    {
      return MemberwiseClone(); //          
    }
  }
 
3.복사 효과 테스트
① 원래 대상 이 이전 값 형식 과 참조 형식 구성원 의 값 을 복사 합 니 다.
② 기 존 대상 을 복사 하여 복사 대상 값 형식 과 참조 형식 구성원 의 값 을 출력 합 니 다.
③ 원래 대상 의 값 을 바 꾸 고 원래 대상 의 값 형식 과 참조 형식 구성원 의 값 을 다시 인쇄 합 니 다.
④ 복사 대상 값 형식 과 참조 형식 구성원 의 값 을 다시 인쇄 합 니 다.

static void Main(string[] args)
{
  Room room1 = new Room(60);
  Film film1 = new Film("    ");
  Cinema cinema1 = new Cinema(room1, film1);
  Cinema cinema2 = (Cinema)cinema1.Clone();
  Console.WriteLine("    ,         {0},           {1}", cinema1._film._name,cinema1._room._maxSeat);

  Console.WriteLine("    ,           {0},           {1}", cinema2._film._name, cinema2._room._maxSeat);

  //              
  cinema1._film._name = "    ";
  cinema1._room._maxSeat = 80;

  Console.WriteLine("    ,         {0},           {1}", cinema1._film._name, cinema1._room._maxSeat);
  Console.WriteLine("    ,           {0},           {1}", cinema2._film._name, cinema2._room._maxSeat);

  Console.ReadKey();
}
실행 결 과 는 다음 과 같 습 니 다.

분석:
얕 은 복사 의 관건 은 인용 유형 에 대한 복사 가 대상 참조 이 며,이 인용 은 위탁 관리 더미 의 대상 인 스 턴 스 를 가리킨다.원래 인용 형식의 값 을 바 꾸 면 복사 대상 에 영향 을 줄 수 있 습 니 다.
깊이 복사
1.'딥 카피'란 무엇 인가
구성원 이 가리 키 는 대상 을 참조 하여 복사 하고 위탁 관리 더미 에 원래 대상 인 스 턴 스 에 포 함 된 데 이 터 를 부여 한 다음 위탁 관리 더미 에 새로운 대상 인 스 턴 스 를 만 듭 니 다.
2.각 대상 멤버 를 복사 하여 딥 카피

    public object Clone()
    {
      Room room = new Room();
      room._maxSeat = this._room._maxSeat;//                 
      Film film = this._film; //       
      Cinema cinema = new Cinema(room, film);
      return cinema;
    }
 
3.서열 화 와 반 서열 화 를 통 해 심도 있 게 복사 할 수 있다

    public object Clone1()
    {
      BinaryFormatter bf = new BinaryFormatter();
      MemoryStream ms = new MemoryStream();
      bf.Serialize(ms, this); //     
      ms.Position = 0;
      return (bf.Deserialize(ms));
    }

4.직렬 화 와 반 직렬 화 깊 은 복사 본 을 사용 하지만 모든 종 류 를[Serializable]로 연결 해 야 합 니 다.테스트 코드 는 다음 과 같 습 니 다.

  [Serializable]
  public class Room
  {
    public int _maxSeat;
 
    public Room()
    {}
 
    public Room(int maxSeat)
    {
      this._maxSeat = maxSeat;
    }
  }
 
  [Serializable]
  public struct Film
  {
    public string _name;
 
    public Film(string name)
    {
      this._name = name;
    }
  }
 
  [Serializable]
  public class Cinema
  {
    public Room _room;
    public Film _film;
 
    public Cinema(Room room, Film film)
    {
      this._room = room;
      this._film = film;
    }
 
    //   
    //public object Clone()
    //{
    //  return MemberwiseClone(); //          
    //}
 
    //               
    public object Clone()
    {
      Room room = new Room();
      room._maxSeat = this._room._maxSeat;//                 
      Film film = this._film; //       
      Cinema cinema = new Cinema(room, film);
      return cinema;
    }
 
    //              
    public object Clone1()
    {
      BinaryFormatter bf = new BinaryFormatter();
      MemoryStream ms = new MemoryStream();
      bf.Serialize(ms, this); //     
      ms.Position = 0;
      return (bf.Deserialize(ms));
    }
  }
5.복사 효과 테스트
① 원래 대상 이 이전 값 형식 과 참조 형식 구성원 의 값 을 복사 합 니 다.
② 기 존 대상 을 복사 하여 복사 대상 값 형식 과 참조 형식 구성원 의 값 을 출력 합 니 다.
③ 원래 대상 의 값 을 바 꾸 고 원래 대상 의 값 형식 과 참조 형식 구성원 의 값 을 다시 인쇄 합 니 다.
④ 복사 대상 값 형식 과 참조 형식 구성원 의 값 을 다시 인쇄 합 니 다.

 static void Main(string[] args)
    {
      Room room1 = new Room(60);
      Film film1 = new Film("    ");
      Cinema cinema1 = new Cinema(room1, film1);
      Cinema cinema2 = (Cinema)cinema1.Clone1();
      Console.WriteLine("    ,         {0},           {1}", cinema1._film._name,cinema1._room._maxSeat);
 
      Console.WriteLine("    ,           {0},           {1}", cinema2._film._name, cinema2._room._maxSeat);
 
      //              
      cinema1._film._name = "    ";
      cinema1._room._maxSeat = 80;
 
      Console.WriteLine("    ,         {0},           {1}", cinema1._film._name, cinema1._room._maxSeat);
      Console.WriteLine("    ,           {0},           {1}", cinema2._film._name, cinema2._room._maxSeat);
 
      Console.ReadKey();
    }
결과:
 
분석:
깊이 복사 한 후 두 대상 의 인용 구성원 은 이미 분리 되 었 으 며,원래 대상 의 인용 유형 구성원 의 값 을 바 꾸 는 것 은 복사 대상 의 인용 유형 구성원 값 에 영향 을 주지 않 습 니 다.

좋은 웹페이지 즐겨찾기