[More Effective C#] 2장 - Item 24: 설계 선택지를 제한하는 IClonable은 사용을 피하라

SY·2023년 10월 28일

More Effective C#

목록 보기
24/46
post-thumbnail

빌 와그너, ⌜More Effective C# 2판⌟, 김완섭 옮김, 한빛미디어, 2019
이 포스팅은 ⌜More Effective C# 2판⌟의 내용을 기반으로 작성되었습니다.


아이템 24: 설계 선택지를 제한하는 IClonable은 사용을 피하라


ICloneable 인터페이스

  • 복제 지원 인터페이스
  • 메서드 : Clone()
  • 구현 예시
public class Person : ICloneable
{
    public int Age { get; set; }
    public int id { get; set; }

    public object Clone()
    {
        return this.MemberwiseClone();
    }
}



IClonable은 구현한 타입이 상속 계통에 있다면, 파생 타입에도 영향을 끼친다.
즉, IClonable을 지원하기로 한 타입의 하위 타입도 IClonable을 지원해야 한다.



IClonable의 공식적인 정의에서 깊은 복사 또는 얕은 복사를 지원 한다고 애매하게 정의하고 있다.
깊은 복사나 얕은 복사를 혼용하면 일관성에 문제가 되기 때문에 대부분의 경우 ICloneable을 완전히 배제하고 타입을 작성하는 것이 낫다.


값 타입의 경우

  • 간단한 할당 연산만으로 수행할 수 있기 때문에 굳이 Clone()함수를 사용할 필요가 없다.

참조 타입을 포함하는 값 타입의 경우

  • 예 : 값 타입이 문자열을 포함하는 경우
  • 일반적인 참조 타입에서 나타나는 문제가 발생하지 않는다.
    • string은 값을 변경하면 새로운 string 객체가 만들어지기 때문이다.

다양한 타입의 참조 필드를 가지는 일반적인 구조체의 경우

  • 깊은 복사를 하려면 구조체 내에 포함된 참조 타입을 모두 새롭게 복사해야 하는데, 이때 해당 타입의 Clone() 메서드가 깊은 복사를 지원하는지 알아야 한다.
  • 해당 타입에 포함된 참조 타입들도 ICloneable을 지원해야 하고 그 Clone()도 깊은 복사를 수행해햐만 한다.
  • 전체 계층 구조에서 IClonable을 반드시 구현해야 하는 경우라면 파생 클래스에서 베이스 클래스의 멤버들을 복사할 수 있도록 복사 생성자를 protected로 구현하면 효과적이다.


IClonable은 예외적인 상황에 대응하기 위한 것으로 보는 편이 낫다.
파생 클래스에서 IClonable을 사용할 가능성이 큰 베이스 클래스라면 protected 복사 생성자를 만들어야 한다.
이 외의 경우에는 IClonable을 사용하지 말자.

profile
게임 개발 공부

0개의 댓글