2010.07.20 03:33 책 정리/Effective C#

이 포스트를 만든 목적

  • 지하철에서 심심해서

이 포스트의 준비 상황

  • gVim 7.2
  • Microsoft Visual C# 2010 Express

참조 링크

내용

C# 에서 ICloneable 은 무엇인가?

  • C# 에서 기본 제공하는 Interface 이다.
  • 깊은 복사(Deep Copy)를 제공하기 위한 표준이 된 interface 이다.

그렇다면 여기서 나오는 C#의 깊은 복사(Deep Copy)와 얕은 복사(Shallow Copy)란 무엇인가?

다 안다는 전제에서 넘어간다. 참조 링크를 보는게 좋다.

왜 C#에서 ICloneable의 구현을 피해야 하는가?

  • 상속 기반일 경우, 하위/상위에 Clone()에 대한 처리를 꼼꼼하게 해 주어야 하기 때문에

  • 멤버 변수 추가될 경우, 멤버 변수도 Clone() 내부 구현도 바뀌는지 살펴 봐야 하기 때문에
    - 이 경우에 대해선 더 이상 설명하지 않는다. 왜냐하면 생각할 게 없기 때문이다.

만약 ICloneable Interface를 사용할 수 밖에 없을 때는 어떻게 하는가?

우선 무엇이 문제가 될 수 있는지 살펴보면, 다음 코드:

이유는 Derived 클래스가 복사되지 않았으므로, d1.Clone()함수에선 당연히 Base()가 나오기 때문이다. 이러한 상속 중 문제를 해결 하기 위해서, 몇 가지 대안이 있다. 다음:

  • 상속 클래스도 IConeable 을 사용한다.
    - 이 경우 상위 클래스에서 멤버를 private로 만들었을 경우, 접근 불가능 할 수 있어, 복사 할 수 없다.

  • 복사를 할 수 있는 가상 함수를 만들어서 처리한다.
    - 이 경우, 복사를 완벽하게 구현 할 수 있으나, 디자인 자체가 무척 나빠서, 사람이 실수하기 쉽다.
    예제3 참조 : http://www.windojitsu.com/blog/copyctorvsicloneable.html

  • Deep Copy용 복사 생성자를 만든다. 그리고 이 생성자에 protected를 부여한다.
    - 복사 생성자가 DeepCopy가 된다는 것을 나타내지 않기 때문에, 복사 생성자를 protected로 만든 것이다.
    - 내가 보이기엔 이 방법이 제일 무난하다. 형 변환도 적을 뿐더러, 상속 기반에서도 잘 작동한다. 다음 코드:

결론

  • 복잡한 경우가 생길 수 있으므로, 되도록 구현을 피하고, 어쩔수 없을 땐, 복사 생성자를 만들어서 구현하자.

여담

  • 영어 공부는 필수인가 보다. 찾는 정보마다 다 영어여서, 코드 없으면 까막눈이다.
  • Value Type 안에 Referece Type이 있을 경우, Clone을 구현하지 않고, Referece만 복사 하는게 더 좋다.

  • 만들고 나니까, 복사 생성자를 public 으로 만들고 Deep Copy 플래그를 주고, 결정해도 무난해 보인다. : )


posted by 농사를 짓는 게임 프로그래머 최익필

댓글을 달아 주세요

  1. Favicon of http://six605.tistory.com six605 2010.07.20 08:54  Addr  Edit/Del  Reply

    잘 보고 갑니다. ^^

  2. Favicon of https://coderlife.tistory.com 요원009 2016.11.01 14:23 신고  Addr  Edit/Del  Reply

    예제가 깔끔하니 좋네요. 잘 봤습니다.

    저는 구조체에 ICloneable을 상속받게 해서 구현 중인데, 혹시 이 부분도 다뤄보셨나요?