GN⁺: C#의 Type Unions 공식 제안
(github.com/dotnet)요약
C#에서 타입 유니언(또는 구별된 유니언)을 제안하는 문서임.
동기
- 소프트웨어 개발 시 변수에 저장할 값이 항상 같은 종류가 아닐 수 있음.
- 예를 들어, 고객과 공급자 정의가 일부 속성만 공유할 때, 두 타입에 대해 유사한 작업을 수행해야 할 수 있음.
- 상속을 통해 해결할 수 있지만, 모든 상황에 적합하지 않음.
- C#에서 제한된 수의 다른 타입을 같은 변수에 저장할 수 있는 방법이 필요함.
- 다른 언어들은 이미 이런 기능을 제공하고 있음.
해결책
- C#에서 유니언 타입을 구현하는 가장 적절한 방법은 추상 기본 클래스를 사용한 계층 구조로 생각할 수 있음.
- 그러나 계층 구조의 제약, 관련 없는 타입의 유니언 표현 불가능 등의 문제점이 있음.
- 여러 종류의 유니언이 필요할 수 있으며, 이 제안은 네 가지 카테고리로 분류함.
표준 - 유니언 클래스
선언
- 유니언 클래스는 enum과 유사하게 선언됨.
- 각 멤버는 상태 변수를 가질 수 있음.
생성
- 멤버 타입의 인스턴스를 할당하여 생성됨.
해체
- 타입 테스트와 패턴 매칭을 통해 해체됨.
포괄성
- 모든 멤버 타입이 switch 표현식이나 문에서 고려되면 기본 케이스가 필요 없음.
널 가능성
- 표준 널 가능성 표기법을 사용하여 널을 포함할 수 있음.
구현
- 유니언 클래스는 추상 레코드 클래스로 구현됨.
특수화 - 유니언 구조체
선언
- 유니언 클래스와 유사하게 선언되지만, struct 키워드가 추가됨.
생성
- 멤버 타입의 인스턴스를 할당하여 생성됨.
해체
- 타입 테스트와 패턴 매칭을 통해 해체됨.
포괄성
- 모든 멤버 타입이 switch 표현식이나 문에서 고려되면 기본 케이스가 필요 없음.
널 가능성
- 표준 널 가능성 표기법을 사용하여 널을 포함할 수 있음.
기본값
- 유니언 구조체는 할당되지 않거나 기본값으로 할당될 때 정의되지 않은 상태일 수 있음.
구현
- 유니언 구조체는 구조체로 구현되며, 멤버 타입은 중첩된 레코드 구조체로 구현됨.
임시 - 임시 유니언
문법
- 임시 유니언은
or
패턴 문법을 사용하여 참조됨.
명명
- 파일 또는 전역 using 별칭을 사용하여 임시 유니언에 공통 이름을 부여할 수 있음.
생성
- 멤버 타입의 인스턴스를 할당하여 생성됨.
해체
- 타입 테스트와 패턴 매칭을 통해 해체됨.
포괄성
- 모든 멤버 타입이 switch 표현식이나 문에서 고려되면 기본 케이스가 필요 없음.
널 가능성
- 표준 널 가능성 표기법을 사용하여 널을 포함할 수 있음.
상호 교환성
- 동일한 멤버 타입을 가진 임시 유니언은 상호 교환 가능함.
사용자 정의 유니언
- 유니언 클래스나 유니언 구조체로 지정할 수 없는 유니언 타입을 선언할 수 있음.
-
Closed
속성을 사용하여 계층 구조를 닫을 수 있음. -
Union
속성을 사용하여 구조체 래퍼로 구현할 수 있음.
공통 유니언
Option
- 값이 존재할 수도 있고 존재하지 않을 수도 있는 값을 나타내는 구조체 유니언임.
Result
- 함수에서 성공적인 결과나 오류를 반환하는 구조체 유니언임.
관련 제안
닫힌 계층 구조
-
Closed
속성을 사용하여 추상 기본 타입에 닫힌 하위 타입 집합을 선언함.
싱글톤 값
- 싱글톤 속성을 가진 타입은 비타입 컨텍스트에서 값으로 사용될 수 있음.
중첩 멤버 단축
- 바인딩되지 않은 이름을 사용하여 타겟 타입의 정적 멤버나 중첩 타입에 바인딩할 수 있음.
GN⁺의 정리
- 이 문서는 C#에서 타입 유니언을 제안하며, 다양한 상황에서 변수에 여러 타입을 저장할 수 있는 방법을 제공함.
- 다른 언어들이 이미 제공하는 기능을 C#에서도 도입하려는 시도임.
- 개발자들이 코드의 가독성과 유지보수성을 높이는 데 도움이 될 수 있음.
- 비슷한 기능을 제공하는 다른 언어의 예로는 F#이 있음.
Hacker News 의견
-
F#에서 차별화된 유니온을 사용해왔고, C#에도 있을 것이라 생각했음
- Java를 사용 중이며, ADT가 없는 언어로 돌아가는 것이 어렵다고 느끼고 있음
- C#의 주요 기능 부족을 사과할 필요가 없어져 기쁨
-
"타입 유니온"이라는 용어가 생소함
- ML 계열 언어의 태그 유니온과 유사해 보임
- C# 개발자들이 기존 용어와 다른 이름을 만드는 경향이 있는지 궁금함
-
오랜 C# 개발자로서 이 제안의 사용 사례가 명확하지 않다고 느낌
- 빈 인터페이스와 레코드 클래스를 선언하여 구현할 수 있을 것 같음
- 놓치고 있는 부분이 있는지 궁금함
-
TypeScript에는 타입 유니온이 있음
- F#이나 Haskell의 차별화된 유니온과 유사해 보임
- 차별화된 유니온에는 명명된 케이스 생성자가 있음
-
패턴 매칭이 가능한 유니온이 없으면 프로그래밍이 어려워짐
- 표현 문제의 의미를 완전히 이해하지 못했음
- 기존 다형성을 통한 확장 포인트 제공이 미래의 클라이언트에게 적합할 수 있음
- 팀이 소유한 코드에는 패턴 매칭이 가능한 유니온이 더 적합함
-
C# 유니온에서 필드 오프셋을 사용한 경험이 있음
- 포인터/참조 값과 값의 별칭이 정의되지 않은 동작을 유발할 수 있음
- u64와 객체의 구조체 유니온은 별도의 필드를 필요로 하여 8바이트를 낭비할 수 있음
-
비공개 생성자와 nuget 패키지를 사용하여 스위치 타입이
_
케이스를 필요로 하지 않도록 함- 제안된 "유니온 클래스"의 디슈가 버전과 유사함
- nuget 패키지가 불필요해지고 문법적 설탕이 추가되는 것이 좋음
-
유니온 구조체가 동시 수정 시 찢어짐을 어떻게 처리하는지 언급되지 않음
- 찢어짐은 메모리 안전 문제를 유발할 수 있음
- 동일한 오프셋에 정수 필드와 참조 필드를 가진 변형이 있을 수 있음