1P by neo 1달전 | favorite | 댓글 1개

요약

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 패키지가 불필요해지고 문법적 설탕이 추가되는 것이 좋음
  • 유니온 구조체가 동시 수정 시 찢어짐을 어떻게 처리하는지 언급되지 않음

    • 찢어짐은 메모리 안전 문제를 유발할 수 있음
    • 동일한 오프셋에 정수 필드와 참조 필드를 가진 변형이 있을 수 있음