열거 형 및 일치하는 속성에 대한 C # 명명 규칙


93

나는 종종 자신의 상태 속성을 열거 형으로 유지하는 클래스를 구현하는 것을 발견합니다. 상태 열거 형과 상태 유형의 ONE 상태 속성이 있습니다. 이 이름 충돌을 어떻게 해결해야합니까?

public class Car
{
  public enum Status
  {
    Off,
    Starting,
    Moving
  };

  Status status = Status.Off;

  public Status Status // <===== Won't compile =====
  {
    get { return status; }
    set { status = value; DoSomething(); }
  }
}

Status 열거 형이 다른 유형에 공통적이라면 클래스 외부에두면 문제가 해결 될 것입니다. 그러나 Status는 Car에만 적용되므로 클래스 외부에서 열거 형을 선언하는 것은 의미가 없습니다.

이 경우 어떤 명명 규칙을 사용합니까?

주의 :이 질문은 일부의 답변의 의견에 논란이 된 이 질문 . 주요 질문 이 아니기 때문에 가시성이별로 없었습니다.

편집 : Filip Ekberg는 '상태'의 특정 경우에 대한 IMO 훌륭한 해결 방법을 제안합니다. 그러나 Michael Prewecki의 답변 에서와 같이 열거 형 / 속성의 이름이 다른 솔루션에 대해 읽으면 흥미로울 입니다.

EDIT2 (2010 년 5 월) : 내가 가장 좋아하는 솔루션은 Chris S가 제안한대로 열거 형 유형 이름을 복수화하는 것입니다. MS 지침에 따르면 플래그 열거 형에만 사용해야합니다. 하지만 점점 더 좋아하게되었습니다. 이제 일반 열거 형에도 사용합니다.


1
클래스 내부에 열거 형을 중첩시키고 싶다면 이에 대한 좋은 해결책이 많지 않다고 생각합니다. 나는 실제로 enum을 분리하는 것을 선호하며 문제를 일으키지 않지만 그것을 중첩하려는 것에 대한 당신의 요점을 철학적으로 볼 수 있습니다.
Craig Shearer

답변:


32

나는 토론에 1 유로를 추가 할 것이지만 아마도 새로운 것을 추가하지 않을 것입니다.

확실한 해결책은 Status를 중첩 된 Enum에서 제거하는 것입니다. 대부분의 .NET 열거 형 (Windows.Forms 네임 스페이스의 일부 제외)은 중첩되지 않으며 API를 사용하는 개발자가 클래스 이름을 접두사로 지정해야하는 데 불편 함을줍니다.

언급되지 않은 한 가지는 MSDN 지침에 따른 플래그 열거 형 은 이미 알고 있는 복수형 명사 여야한다는 것입니다 (상태는 단순 열거 형이므로 단수 명사를 사용해야 함).

State (State라고하는 열거 형)는 어휘이며, "Status"는 대부분의 우리 언어와 같은 영어가 라틴어에서 흡수 한 명사의 명사입니다. Vocative는 조건에 대해 명사를 명명하는 것이며 명사는 동사의 주제입니다.

즉, 자동차 가 움직일 때 동사가 움직이고있는 것이 그 상태입니다. 그러나 차는 꺼지지 않고 엔진이 작동합니다. 엔진이 시작되지도 않고 엔진도 작동합니다 (여기에서 예제를 선택했기 때문에 관련이 없을 수 있습니다).

public class Car
{
  VehicleState _vehicleState= VehicleState.Stationary;

  public VehicleState VehicleState 
  {
    get { return _vehicleState; }
    set { _vehicleState = value; DoSomething(); }
  }
}

public enum VehicleState
{
    Stationary, Idle, Moving
}

상태는 그러한 일반화 된 명사입니다. 어떤 상태를 가리키는 지 설명하는 것이 더 낫지 않습니까? 위에서했던 것처럼

내보기의 유형 예제는 독자 유형이 아니라 해당 데이터베이스를 참조합니다. 독자의 유형과 반드시 ​​관련이없는 독자의 데이터베이스 제품을 설명하는 경우 선호합니다 (예 : 독자 유형은 포워드 전용, 캐시 등). 그래서

reader.Database = Databases.Oracle;

실제로 이것은 열거 형을 사용하는 대신 드라이버 및 상속 체인으로 구현되므로 절대 발생하지 않으므로 위의 줄이 자연스럽게 보이지 않습니다.


24
내 이해는 플래그는 단순한 열거 형이 아니라 복수형이어야한다는 것입니다.
Serge Wautier

8
열거 형을 클래스 밖으로 이동하는 것과 관련하여 CarState가 Car.State보다 편리한 이유를 아직 이해하지 못했습니다. 그러나이 열거 형이이 클래스의 동작 만 설명 할 때 클래스에서 열거 형을 가져 오는 긍정적 인 측면을 이해하지 못합니다.
Serge Wautier

명사뿐만 아니라 FileOptions와 같은 명사구를 작성해야했고 답변을 업데이트했습니다. 나는 classname.Enum이 단지 기본 설정이라고 생각합니다. 프레임 워크에서 내가 복사하게 될 예제를 찾을 수 없습니다.
Chris S

MS는 플래그를 위해 복수형을 유지해야한다고 말했지만 시간이 지남에 따라 그 솔루션을 점점 더 좋아하게되었습니다. 이제 열거 형에도 사용합니다. 따라서 나는 내 마음을 바꾸고 Filip 대신 당신의 대답을 받아 들였습니다.
Serge Wautier

1
내가 여기에 1 년 반 늦었다는 건 알지만 예를 public class EngineState들어야 public enum EngineState하죠?
David Murdoch

36

"Off", "Starting"및 "Moving"의 정의는 "State"라고 부르는 것입니다. 그리고 당신이 "상태"를 사용하고 있다는 것을 암시 할 때 그것은 당신의 "상태"입니다. 그래서!

public class Car
{
  public enum State
  {
    Off,
    Starting,
    Moving
  };

  State state = State.Off;

  public State Status
  {
    get { return state ; }
    set { state= value; DoSomething(); }
  }
}

이 경우에 "유형"이라는 단어를 사용하려는 위치에 명시된 다른 예를 들면 다음과 같습니다.

public class DataReader
{
    public enum Type
    {
        Sql,
        Oracle,
        OleDb
    }

    public Type Type { get; set; } // <===== Won't compile =====

}

enum과 enum 사이에 차이가 있다는 것을 정말로 알아야합니다. 하지만 프레임 워크를 만들거나 아키텍처에 대해 이야기 할 때 유사성에 초점을 맞춰야합니다.

어떤 것이 상태로 설정되면 "사물"상태로 정의됩니다.

예 : 자동차의 상태는 Running State, Stopped State 등입니다.

두 번째 예제에서 달성하고자하는 것은 다음과 같습니다.

myDataReader.Type = DataReader.Database.OleDb

이것이 내가 다른 사람들에게 설교 해 온 것에 대해 표준을 따라야한다고 생각할 수도 있습니다. 그러나 당신은 표준을 따르고 있습니다! Sql-case는 또한 특정 케이스이므로 다소 구체적인 솔루션이 필요합니다.

그러나 열거 형은 System.Data공간 내에서 재사용이 가능 하며 패턴이 전부입니다.

"유형"으로 살펴볼 또 다른 경우는 유형이 종을 정의하는 "동물"입니다.

public class Animal
    {
        public enum Type
        {
            Mammal,
            Reptile,
            JonSkeet
        }

        public Type Species{ get; set; }

    }

이것은 패턴을 따르고 있으며,이를 위해 Object를 특별히 "알 필요가 없으며" "AnimalType"또는 "DataReaderType"을 지정하지 않습니다. 선택한 네임 스페이스에서 열거 형을 재사용 할 수 있습니다.


1
"상태"이름은 단지 예일 뿐이라고 생각합니다. 상태 / 상태에 의존 할 수없는 다른 상황은 어떻습니까? 예 : 유형 열거 형 ...
Dan C.

이에 대한 예제 시나리오를 제공해 주시겠습니까? 병 : 그 aswell에 따라 내 대답을 확장하려고
필립 에크 베르그

2
@Filip : Animal Type 샘플은 첫 번째 주석에서 내가 의미하는 바를 정확히 지적합니다. 즉, 이것은 열거 형을 거의 "다시 표현"한 것입니다. 열거 형과 속성 이름에 동의어를 사용하면 코드가 다소 혼란스러워집니다.
Dan C.

1
나는 또한 '종'은 단지 유형 (이 경우 동물의 경우)의 재 문어라고 생각합니다.
LegendLength

2
단순히 이름을 바꾸는 것이 항상 그렇게 깨끗한 것은 아닙니다. 예를 들어 열거 형 Suit 및 속성 Suit가있는 카드 용 클래스를 생각해보십시오. 정확히 무엇으로 이름을 바꿉니 까? 어느 쪽이든 서투른.
annakata

9

여기서 진짜 문제는 열거 형 상태가 클래스 내에서 캡슐화되어 Car.Status속성 Status과 열거 형 모두에 대해 모호 하다는 것 입니다.Status

더 나은 방법은 열거 형을 클래스 외부에 두는 것입니다.

public enum Status
{
    Off,
    Starting,
    Moving
}

public class Car
{
    public Status Status
    { ... }
}

최신 정보

아래 설명에 따라 위의 디자인을 설명하겠습니다.

나는 열거 형이나 클래스 또는 다른 객체가 해당 클래스 내에서 완전히 비공개되지 않는 한 다른 클래스 내에 있어야한다고 믿지 않는 사람입니다 . 예를 들어 위의 예를 살펴 보겠습니다.

public class Car
{
    public enum Status
    {...}
    ...
    public Status CarStatus { get; set;}
}

일부 주석가는 Status가 Car 클래스의 범위를 벗어난 의미가 없다고 주장하지만 공용 속성을 설정한다는 사실은 해당 열거 형 사용할 프로그램의 다른 부분이 있음을 의미합니다 .

public Car myCar = new Car();
myCar.CarStatus = Car.Status.Off;

그리고 그것은 나에게 코드 냄새입니다. 나는 그 상태에서 볼거야 경우 외부Car, 나는뿐만 아니라 그것을 정의 할 수 있습니다 외부 뿐만 아니라.

따라서 이름을 다음과 같이 변경하겠습니다.

public enum CarStatus
{...}

public class Car
{
    ...
    public CarStatus Status { get; set; }
}

그러나 해당 enum이 car 클래스 내에서만 사용되는 경우 enum 을 선언해도 괜찮습니다.


이렇게하면 Status가 전역 적으로 만들어 지므로 특정 영역 내에 있어야합니다. "인간"과 같은 다른 유형의 "상태"에는 "시작"이 없을 수 있습니다. 그러나 패턴을 따라야합니다.
Filip Ekberg

아니에요. 열거 형은 99 %의 경우 속성에 사용하려는 동일한 단어입니다. 열거 형은 이름이 지정된 플래그 일 뿐이므로 외부 생활에 거의 해를 끼치 지 않습니다 (논리를 포함하는 클래스와 달리)
Quibblesome

Jon, 이것이 바로 제 요점입니다. Status 열거 형은 Car에 대해서만 의미가 있습니다. 완전히 다른 유형의 객체는 완전히 다른 상태를
갖습니다

그들은 그래서 문제가되지 않습니다,하지만 다른 네임 스페이스에 있습니다
크리스 S

차 밖에서보고 싶다는 설명은 말이됩니다. 하지만 내 경우에는 내가 두 개의 클래스를 가지고 ORCR. 둘 다 자체 상태 집합이 있으므로 자체 범위 외부에서 정의 할 수있는 옵션이 아닙니다.
deed02392

4

내 제안이 .NET 명명 규칙에 위배된다는 것을 알고 있지만, 개인적으로 enum 앞에 'E'를 붙이고 enum 플래그에 'F'를 붙입니다 (Interfaces에 'I'라는 접두사를 붙이는 것과 비슷합니다). 나는 이것이 왜 컨벤션이 아닌지 이해하지 못합니다. 열거 형 / 플래그는 유형을 변경하지 않는 인터페이스와 같은 특수한 경우입니다. 그것이 무엇인지 명확하게 할뿐만 아니라 접두사가 대부분의 다른 유형 / 변수 / 등을 필터링하고 이러한 이름 충돌이 발생하지 않기 때문에 intellisense를 입력하는 것은 매우 쉽습니다.

또한 WPF의 예제에서 미리 정의 된 유형의 인스턴스가있는 열거 형 (예 : FontWeights)과 같은 정적 클래스를 사용하지만 검색하지 않으면 알 수없는 또 다른 문제를 해결할 수 있습니다. 'E'를 접두사로 붙이면 이러한 특수 정적 클래스를 찾기 위해 문자를 입력하기 만하면됩니다.


4

헝가리 표기법과 그 변형을 싫어하는 사람들은 저주를받습니다. 나는-wait for it-접미사 enums를 사용합니다 Enum. 결과적으로 나는 당신이 설명하는 문제가 전혀 없으며, 무엇을 호출할지 걱정하는 시간을 낭비하고 코드는 읽기 쉽고 자체 설명 적입니다.

public class Car
{
  public enum StatusEnum
  {
    Off,
    Starting,
    Moving
  };

  public StatusEnum Status { get; set; }

}

9
마이크로 소프트의 규칙 것을 불구하고 유의하시기 바랍니다 열거 명명은 말합니다 : X DO가 NOT 열거 형 이름에 "열거"접미사를 사용합니다.
DavidRR

2
Microsoft의 규칙은 시간의 시험을 견디는 것으로 입증 되었기 때문입니다.
nathanchere 2014 년

2

속성 이름을 "CurrentStatus"와 같은 이름으로 변경하겠습니다. 빠르고 쉽게 :)


1

유형 이름 (또는 비트 플래그가 포함 된 경우 Flag)에 "Option"을 추가하는 것이 좋습니다. 즉, 유형은 Car.StatusOption이고 속성은 Car.Status입니다.

복수화와 비교하여, 이것은 일반적으로 enum 유형이 아닌 collection 속성 을 복수화하려는 enum 유형의 컬렉션을 만들 때 이름 충돌을 방지 합니다 .


0

나는 보통 CarStatus와 같은 enum을 접두사로 붙입니다. 나는 그것이 모두 당신이 함께 일하는 팀 (그 종류의 규칙 / 프로세스가 있다면)과 객체 사용에 달려 있다고 생각합니다. 내 2 센트 (:


1
이것은 실제로 MyObjectName이 Status 앞에있는 명명 규칙을 죽일 것입니다.
Filip Ekberg

클래스의 네임 스페이스는 어쨌든이 문제를 처리하기에 충분 해야 합니다
annakata
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.