이 포스트를 만든 목적
- 지하철에서 심심해서
이 포스트의 준비 상황
- gVim 7.2
- Microsoft Visual C# 2010 Express
참조 링크
- http://six605.tistory.com/407
- http://www.java2s.com/Tutorial/CSharp/0140__Class/CreateacloneusingtheObjectMemberwiseClonemethodbecausetheEmployeeclasscontainsonlystringandvaluetypes.htm
- http://en.csharp-online.net/ICloneable
- http://rea1man.tistory.com/entry/C-Shallow-Copy-구현얕은-복사
내용
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 플래그를 주고, 결정해도 무난해 보인다. : )
'책 정리 > Effective C#' 카테고리의 다른 글
item 32, 작고 응집도가 높은 어셈블리가 더 좋다. (0) | 2010.07.31 |
---|---|
item 31, 작고 단순한 메서드가 더 좋다. (0) | 2010.07.25 |
item 30, CLS를 준수하는 어셈블리가 더 좋다. (0) | 2010.07.25 |
item 29. 기반 클래스의 변경이 영향을 줄 경우에만 new 한정자를 사용하라. (0) | 2010.07.22 |
item 28, 형변환 연산자의 구현을 피하라 (0) | 2010.07.21 |
item 26, IComparable과 IComparer를 이용하여 순차관계를 구현하라 (6) | 2010.07.19 |
item 25, serializable 타입이 더 좋다. (0) | 2010.07.18 |
item 24, 명령적 프로그래밍보다 선언적 프로그래밍이 더 좋다. (0) | 2010.07.14 |
item 23, 클래스 내부 객체에 대한 reference 반환을 피하라. (0) | 2010.07.11 |
item 22, 이벤트를 이용하여 외부로 노출할 인터페이스를 정의하라. (0) | 2010.07.10 |
최근댓글