앞서 생성자 내에서 여러 개의 속성에 값을 할당하는 작업을 단일 표현식으로 나타내기 위해 튜플을 활용하는 기법을 보여준 바가 있다. 혹시 여기서도 동일한 방법을 사용할 수는 없을까? 답은 ‘그렇다’이다. 사용할 수 있다. 그리고 개인적으로 이런 방법을 매우 선호한다. 다음 코드에 생성자와 Deconstruct 메서드를 함께 나타냈는데, 이 둘이 매우 비슷해 보인다.
public Point(double x, double y) => (X, Y) = (x, y);
public void Deconstruct(out double x, out double y) => (x, y) = (X, Y);
이 같은 코드에 익숙해지기만 한다면 더할 나위 없이 간단하고 아름다운 코드다.
분해를 위한 Deconstruct 인스턴스 메서드 작성 규칙은 매우 단순하다.
• 분해를 위한 코드에서 접근 가능한 메서드여야 한다(예를 들어, 모든 코드가 동일한 어셈블리 내에 있다면 Deconstruct 메서드를 internal 메서드로 선언할 수도 있다).
• 반환 타입은 void여야 한다.
• 매개변수는 적어도 두 개 이상이어야 한다(하나의 값을 분해할 수는 없다).
• 제네릭이 아니어야 한다.
Deconstruct 메서드를 설계할 때 매개변수 없이 튜플 타입을 반환하도록 코드를 작성하는 대신 out 매개변수를 사용하는 이유가 의아할 수도 있다. 실제로 Deconstruct 메서드를 구성할 때 여러 가지 타입으로 인스턴스를 분해하도록 하면 상당히 유용할 것이다. 이를 위해 다양한 형태의 오버로드를 정의할 수도 있다. 하지만 튜플을 반환하게 하면 반환 타입만 달라지므로 여러 개의 오버로드를 작성하는 것이 불가능해진다. 좀 더 명확히 살펴보기 위해서 DateTime을 분해하는 예를 살펴볼 것이다. 당연한 이야기지만 DateTime 내에 인스턴스 메서드를 추가할 수는 없으므로 확장 메서드를 이용하여 Deconstruct 메서드를 작성할 것이다.