2010-02-13 6 views
23

herehere과 관련된 몇 가지 관련 질문이 있지만 만족스러운 답변을 제공하지 못했습니다. 문제는 C#의 클래스에 중첩 된 enum은 클래스의 속성과 동일한 이름을 가질 수 없다는 것입니다. 내 예 :중첩 열거 형 및 속성 명명 충돌

public class Card 
{ 
    public enum Suit 
    { 
     Clubs, 
     Diamonds, 
     Spades, 
     Hearts 
    } 

    public enum Rank 
    { 
     Two, 
     Three, 
     ... 
     King, 
     Ace 
    } 

    public Suit Suit { get; private set; } 
    public Rank Rank { get; private set; } 
    ... 
} 

이 문제를 해킹하기위한 몇 가지 옵션이 있지만 나에게 맞는 것 같지 않습니다.

클래스 외부로 열거 형을 이동할 수 있지만 Card.Suit 대신 Suit이라고 말하면 잘못된 것 같습니다. Card의 컨텍스트 외부에 Suit은 무엇입니까?

클래스 외부로 이동하여 CardSuitCardRank과 같은 것으로 변경할 수는 있지만 클래스 또는 클래스에서 처리해야하는 열거 형의 이름에 컨텍스트 정보를 베이킹하고있는 것처럼 느낍니다. 이름 공간 이름.

열거 형 이름을 SuitsRanks으로 변경할 수 있지만 Microsoft's naming guidelines을 위반합니다. 그리고 그것은 옳다고 느끼지 않습니다.

속성 이름을 변경할 수 있습니다. 그러나 무엇에? 직관적으로 내게는 Suit = Card.Suit.Spades라고 말하고 싶어합니다.

이 열거 형을 포함하는 CardInfo이라는 개별 정적 클래스로 열거 형을 이동할 수 있습니다. 내가 다른 것을 생각해 낼 수 없다면, 이것이 최선의 선택이라고 생각합니다.

다른 사람들이 비슷한 상황에서 무엇을했는지 궁금합니다. 왜 이것이 허용되지 않는지 아는 것도 좋을 것입니다. 어쩌면 에릭 리 퍼트 (Eric Lippert) 또는 누군가가 금지 결정을 내릴 수 있습니까? 클래스가 안에있는 경우에만 내에 모호성이 생성되고 이는 속성 이름에 this.Suit을 사용하여 해결할 수 있습니다. (지방 주민과 회원 사이의 모호성과 유사합니다.) 나는 이것이 "every feature starts with -100 points" 일로 인해 빠져 나갔다고 가정하지만, 이것에 관한 토론에 대해 궁금 할 것입니다.

+1

의견을 보내 주셔서 감사합니다. 나는'CardInfo'로 갈 것이지만, 여기에 하나의 정식 답이 없다고 생각합니다. 괜찮은 옵션이 많이 있습니다. 그리고 스타일이 좋다고 생각합니다. –

+0

'enum'중첩은 클래스 내부에서 (주로?) 사용하려는 경우 괜찮습니다. 그런 다음 필드/속성과의 이름 충돌을 피하기 위해'enum' *을 약간 다르게 (이름에 * Type *, * Mode *, * Option * 등을 추가) 이름을 붙여야합니다. 그 클래스 밖에서'enum '을 사용하는 사용자가 많이있을 경우, 중첩은 나쁜 생각입니다. 동일한 cs-file에서 선언 할 수 있습니다 (사용되는 클래스와 적어도 일종의 관계를 가짐). 중첩은 wpf에서 바람직하지 않습니다 (반드시 'enum'은 아니지만 일반적으로). – Sinatr

답변

18

또한이가 허용되지 않는 이유를 알고 좋은 것입니다. 어쩌면 에릭 리 퍼트 (Eric Lippert) 또는 누군가가 금지 결정을 내릴 수 있습니까?

규칙의 요점은 이름을 찾을 때 클래스 내에 모호성이 없도록하는 것입니다. 특정 코드 영역은 '선언 공간'을 정의하는 것으로 지정됩니다. 선언 공간의 기본 규칙은 동일한 선언 공간에 선언에는 두 가지

이 규칙에 대한 예외를 만드는 (서명하지 이름. 차이가해야하는, 방법 제외) 같은 이름이 없습니다 입니다 그냥 혼란스럽지 않고 혼란스럽게 만듭니다. 나는 당신이 동일한 선언 공간에서 선언 된 같은 이름의 속성과 열거 형을 가질 수 없다는 것을 당황스럽게 생각합니다. 그러나 예외를 만들기 시작하면 엉망이됩니다. 일반적으로 이라는 이름의 고유 한 속성 인은 메소드 그룹, 유형 매개 변수, 속성 등을 식별합니다. 이 규칙이 선언 공간에을 사용 선언 공간에을 선언 일이 아닌 일에 적용

참고. Suit와 같은 선언 공간에 선언되지 않았다면 "public Suit Suit {get; set;}"이라고 말하는 것이 합법적입니다. 누군가가 "Suit.X"라고 말하면, X가 유형 (즉, X는 정적 멤버)인지 속성 (즉, X는 인스턴스 멤버)인지 알아내는 것이 약간 까다 롭습니다.

http://blogs.msdn.com/ericlippert/archive/2009/07/06/color-color.aspx

+0

그건 나에게 의미가 있습니다. 정보 주셔서 감사합니다! –

+0

이 문제를 해결하기위한 표준 명명 규칙이 있습니까? 필자의 경우, 계층 적 (json) 설정 파일의 값을 유지하기 위해 중첩 된 클래스 구조를 만들려고합니다. 내 자연스러운 경향은 중첩 클래스와 같은 속성을 지정하는 것입니다 (예 : 중첩 클래스'Settings.Color'가있는 경우'public Color Color {get; set;}')를 사용하고 싶습니다. 물론 이것은 컴파일되지 않습니다. 내 옵션은 클래스 나 속성의 이름을 바꾸는 것, 예를 들어'ColorInfo' 인 것처럼 보이지만, 이것은 계층 구조의 깊숙한 항목에 대해 못생긴 이름을 만들 수 있습니다. – devuxer

+0

@devuxer : 나는이 문제를 해결하는 좋은 방법을 모르지만, 보통 중첩 된 형식을 만드는 것은 나쁜 냄새로 여겨지므로 걱정하지 않는 것이 일반적입니다. 중첩 형식이 public이 아닌 경우 해당 형식을 노출하는 공용 속성은 절대로 사용하지 마십시오. 나는 중첩 된 타입을 피할 것이다. 중첩 된 형식이 외부 형식의 개인 구현 세부 사항 인 경우에만 사용합니다. –

3

나는 옵션 뒤에 명사를 사용하여 enum을 명명하는 것을 선호합니다. 귀하의 경우에는 : 결국

SuitOptions 
RankOptions 

는, 열거, 바로 가능한 옵션의 단지 설정되어 있습니까? 내 의견으로는 의미가

myCard.Suit = Card.SuitOptions.Clubs; 

을하고 당신은 여전히 ​​텍스트를 볼 수 있는지 여부 다음 열거 나 재산 때 알 수 있습니다

그런 것입니다.

+1

열거 형은 정의에 따라 옵션 집합이므로 이름을 구별하는 것이 바람직하지 않습니다. 스타일 지침에서하지 말아야 할 -Enum 접미사를 추가하는 것과 같습니다. –

+0

-Enum 접미사를 추가하는 것이 불필요하지만 여전히 -Options은 좋은 선택이라고 생각합니다. 그 이유는 "Suits"가 저에게 정장 컬렉션과 단순한 "Suit"를 생각하게 만드는 것입니다. 이 맥락에서 일하고 있습니다. –

+1

-Options이 부적절한 접미사라고 생각하는 열거 형이 있습니까? 나는 그것이 적합하지 않은 곳을 생각할 수 없다. 나는 그것이 문제라고 생각한다. 너무 일반적이다. 그것은 클래스에 -Manager 또는 -Helper와 같습니다. –

1

클래스 정의 외부에서 열거 형을 이동하고 네임 스페이스를 사용하여 카드와 관련 있음을 나타냅니다. 나는 일반적으로 클래스 안에 중첩 된 enum을 좋아하지 않는다. 당신은 복수형에 대한 것이 맞습니다 : 일반적인 enum을위한 단수, flag enum을위한 복수형.

+0

다른 옵션이지만 비슷한 문제가 발생하기 쉽습니다. 네임 스페이스는 무엇을 호출해야합니까? 'Card'는 클래스 이름과 충돌합니다. Enums 네임 스페이스에서 다른 레벨을 중첩시킬 수 있습니다. 클래스 자체가 'Core.Card'인 'Core.Enums.Card'와 같은 것입니다. 그건 나쁜 선택이 아니야. –

1

열거 형은 기본적으로 사용자가 정의한 데이터 유형입니다. 회원 이름으로 'int'또는 'string'을 사용하지 않으므로 귀하의 경우 열거 이름과 회원 이름을 사용하는 것이 좋지 않은 생각입니다.

+0

그래서이 * 특정 * 케이스에서 이름을 지으시겠습니까? 'int'와'string'은 매우 일반적인 것들이지만'Suit'와'Rank'는'Card' 문맥에서만 의미가 있습니다. –

+0

완벽하게 좋은 철학적 위치가 실용적인 현실로 넘어지면 나는 정말로 그것을 싫어한다. 내 자신의 명명 체계에서는 항상 내 재산 이름에 camelCase를 사용하므로 내 재산 선언은 "공공 의상 소송" . 그렇게 할 수 없다면 CardInfo 클래스 아이디어가 마음에 든다. 그리고 CardSuit (당신이 제안한대로) 또는 SuitOptions (빅터)도 나쁘지 않습니다. 때때로, 우리의 객체의 논리적 인 실제 이름은 컴파일러가 우리에게 허용하는 것과 일치하지 않는다고 생각합니다. – Ray

+0

참. 여기서 몇 가지 적절한 옵션이 있지만 아무도 이상적이지는 않습니다. 나는 내'CardInfo'를 향하여 기울이고 있지만, 그렇지 않겠습니까? 나는 결국 그것을 제안했다. 나는 이것이 주로 스타일 선택이라고 생각한다. –

3

열거 형 정의를 별도의 장소로 이동하는 것에 동의합니다.현재 열거 카드를 통해서만 볼 수 있습니다, 그래서 당신은 에이스를 확인하기를 원한다면, 당신은 별도의 정의로 이동 한 경우 당신이 그것을 만든 경우,이 작업을 수행 할 수있는 경우

if (card.CardSuit == Card.Suit.Ace) { } //need different name for Suit field 

을해야 할 것입니다 글로벌 :

if (card.Suit == Suit.Ace) { } //no naming clashes, easier to read 
+1

중첩 된 유형/열거 형은 자주 사용하면 피해야합니다. 예를 들어 IDE/Intellisense를 통해 발견하기가 어렵습니다. "Suit"를 입력 할 때도 자동으로 'using'을 추가 할 프롬프트가 표시되지 않습니다. 열거 형에 'Card.Suit'로 액세스해야하므로 미친 exmaple. 클래스를 내부적으로 만 사용하거나 매우 외부에서 필요로하거나 클래스 상속과 같은 고급 시나리오에서만 사용되는 경우에만 유형을 중첩합니다. – AaronLS

1

It't의 Microsoft Naming Guidelines 말을하는 동안 대부분의 열거 및 비트 필드에 대한 복수의 이름에 대한 단수 이름을 사용하는 것을보고 흥미 the code sample for the enum keyword않습니다 : 우리는 세부 사항이 있음을 어떻게 내 문서를 참조 복수 이름 사용!

enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };