Enum Naming Convention - liczba mnoga

267

Zadaję to pytanie, mimo że przeczytałem podobne, ale nie dokładnie to, czego chcę na konwencji nazewnictwa C # dla wyliczania i dopasowywania właściwości

Odkryłem, że mam tendencję do nazywania liczby mnogiej liczbą mnogą, a następnie „używania” jej w liczbie pojedynczej, na przykład:

public enum EntityTypes {
  Type1, Type2
}

public class SomeClass {
  /*
    some codes
  */

  public EntityTypes EntityType {get; set;}

}

Oczywiście to działa i to jest mój styl, ale czy ktoś może znaleźć potencjalny problem z taką konwencją? Mam jednak „brzydką” nazwę ze słowem „Status”:

public enum OrderStatuses {
  Pending, Fulfilled, Error, Blah, Blah
}

public class SomeClass {
  /*
    some codes
  */

  public OrderStatuses OrderStatus {get; set;}

}

Informacje dodatkowe: Może moje pytanie nie było wystarczająco jasne. Często muszę intensywnie myśleć, nazywając zmienne moich zdefiniowanych typów wyliczeń. Znam najlepszą praktykę, ale nie ułatwia to nazywania tych zmiennych.

Nie mogę ujawnić wszystkich moich właściwości wyliczania (powiedz „Status”) jako „MyStatus”.

Moje pytanie: Czy ktoś może znaleźć potencjalny problem z opisaną powyżej konwencją? NIE chodzi o najlepszą praktykę.

Przeformułowanie pytania:

Cóż, myślę, że powinienem zadać pytanie w ten sposób: Czy ktoś może wymyślić dobry ogólny sposób nazywania typu wyliczeniowego, tak że przy użyciu nazewnictwo „wystąpienia” wyliczenia będzie dość proste?

okej
źródło
5
publiczne wyliczenie OrderState ... - public OrderState OrderStatus {get; set;}
Fraser,

Odpowiedzi:

333

Microsoft zaleca używanie liczby pojedynczej dla Enums, chyba że Enumreprezentuje pola bitowe (użyj FlagsAttributerównież). Zobacz Konwencje nazewnictwa typów wyliczeń (podzbiór Wytycznych nazewnictwa Microsoft ).

Aby odpowiedzieć na twoje wyjaśnienie, nie widzę nic złego w żadnym z poniższych:

public enum OrderStatus { Pending, Fulfilled, Error };

public class SomeClass { 
    public OrderStatus OrderStatus { get; set; }
}

lub

public enum OrderStatus { Pending, Fulfilled, Error };

public class SomeClass {
    public OrderStatus Status { get; set; }
}
Jason
źródło
20
Tak, to poprawna odpowiedź. Te wytyczne są używane w .Net Framework, np. Enum DayOfWeek i flagi enum RegexOptions.
Alexander Zwitbaum,
1
Tak, to zalecana praktyka, cieszę się. Jednak to nie odpowiada na moje pytanie.
okw
1
@okw w celu dalszego opracowania, chociaż wygląda brzydko, jeśli potrzebujesz pojedynczej wartości z wyliczenia flagi, użyj formy pojedynczej dla pola / właściwości / argumentu. Jeśli obsługuje to ustawienie wielu flag, użyj liczby mnogiej. Jeśli twoje wyliczenie nie jest wyliczeniem flag, użyj liczby pojedynczej dla nazwy typu i pola / właściwości / argumentów.
Jonathan Dickinson
4
Oto link do wersji .Net 4.0 przewodnika po konwencjach nazewnictwa Microsoft, do którego link znajduje się w odpowiedzi.
1
@ Thomas Nigdy nie miałem z tym problemu, nie rozumiem, dlaczego to nie zadziała - nie widzę kontekstu, w którym byłoby niejednoznaczne, czy jest to odwołanie do typu czy zmiennej. tzn. OrderStatus == OrderStatus.Pendingjest rozpoznawany jako zmienna dla lewej, a następnie wyliczenie po prawej
James Hurley
39

Zacząłem nazywać wyliczenia w liczbie mnogiej, ale od tego czasu zmieniłem się na liczbę pojedynczą. Po prostu wydaje się mieć większy sens w kontekście miejsca ich użycia.

enum Status { Unknown = 0, Incomplete, Ready }

Status myStatus = Status.Ready;

Porównać do:

Statuses myStatus = Statuses.Ready;

Uważam, że pojedyncza forma brzmi bardziej naturalnie w kontekście. Zgadzamy się, że deklarując wyliczenie, które ma miejsce w jednym miejscu, myślimy „to grupa wielorybów”, ale kiedy go używamy, przypuszczalnie w wielu miejscach, myślimy, że „to jest wszystko jedno” .

Bob Kaufman
źródło
6
Trochę późna reakcja (i może trochę nie na temat), ale: sugerowałbym użycie wartości 0dla nieznanej wartości, w ten sposób niezainicjowana zmienna jest domyślnie Unknown.
SvenL
Zgoda, @ SvenL. Zaktualizowałem odpowiednio przykład.
Bob Kaufman
Czy naprawdę umieściłbyś [Flags]atrybut w swoim przykładzie? Nie ma sensu, aby coś miało zarówno status „Nieukończony”, jak i „Gotowy”. Gdybyś miał enum [Flags]Steps { First, Second, Third }, czy naprawdę nazwałbyś swoją zmienną completedStep?
Pakman
26

Sytuacja tak naprawdę nigdy nie dotyczy liczby mnogiej.

enumPokazuje atrybut coś lub inny. Podam przykład:

enum Humour
{
  Irony,
  Sarcasm,
  Slapstick,
  Nothing
}

Możesz mieć jeden typ, ale spróbuj pomyśleć o nim w wielu, a nie w liczbie mnogiej:

Humour.Irony | Humour.Sarcasm

Zamiast

Humours { Irony, Sarcasm }

Masz poczucie humoru, nie masz humoru.

Kyle Rosendo
źródło
5
Haha, cóż, programiści nie zawsze są poprawni gramatycznie / politycznie. W twoim przypadku prawdopodobnie używam „HumourTypes”. Chyba zły nawyk.
okw
Co jeśli chcę wyszukać wszystkie osoby, które mają poczucie sarkazmu LUB mają poczucie ironii, czy nie podałbym procedurze wyszukiwania wystąpienia Humourszawierającego Humours.Irony | Huomours.Sarcasm?
Charles Bretana,
14

Ogólnie rzecz biorąc, zalecenie dotyczące najlepszych praktyk jest liczbą pojedynczą, z wyjątkiem tych wyliczeń, które mają przypisany atrybut [Flagi] (i które dlatego mogą zawierać pola bitowe), które powinny być w liczbie mnogiej.

Po przeczytaniu edytowanego pytania mam wrażenie, że możesz pomyśleć, że nazwa właściwości lub nazwa zmiennej musi być inna niż nazwa typu wyliczeniowego ... Nie. Następujące jest całkowicie w porządku ...

  public enum Status { New, Edited, Approved, Cancelled, Closed }

  public class Order
  {
      private Status stat;
      public Status Status
      { 
         get { return stat; }
         set { stat = value; }
      }
  }
Charles Bretana
źródło
To prawda, że ​​moja metoda jest „szybkim i leniwym” sposobem na uniknięcie potrzeby myślenia o nazwach podczas używania wyliczeń.
okw
1
Na poparcie Twojej odpowiedzi: w witrynie MSDN od nazw członków typu w sekcji „Nazwy właściwości”: ✓ UWAŻAJ, że właściwość ma taką samą nazwę jak jej typ. Przykład: public Color Color { get {...} set {...} }
DavidRR,
10

To jedno z niewielu miejsc, w których nie zgadzam się z konwencją na tyle, aby przeciwstawić się jej. TBH, NIENAWIDZĘ, że definicja wyliczenia i jego instancja mogą mieć tę samą nazwę. Po dodaniu wszystkich moich Enums wstawiam „Enum”, ponieważ wyjaśnia, w jakim kontekście jest ono używane. IMO sprawia, że ​​kod jest znacznie bardziej czytelny.

public enum PersonTypesEnum {
    smart,
    sad,
    funny,
    angry
}


public class Person {   
    public PersonTypesEnum PersonType {get; set;}
}

Nikt nigdy nie pomyli, co to jest wyliczenie i jakie jest jego wystąpienie.

Wrzos
źródło
2
Przybyłem tutaj, szukając konwencji nazewnictwa enum, po tym, jak klasa i enum nazwano tak samo - i chciałem mieć „coś”, aby było to bardziej oczywiste. Myślałem o dodaniu litery „E” (oczywiście dla Enums), jakbyśmy mieli interfejsy z „ja” - ale podobało mi się twoje rozwiązanie, Heather! Niezłe!!!
Scott
1
Z linii projektowych Microsoftu: „NIE używaj sufiksu„ Enum ”w nazwach typów enum”. docs.microsoft.com/en-us/dotnet/standard/design-guidelines/…
Thoryn Hawley
3
Być może przeoczyłeś BARDZO PIERWSZE zdanie tego, co powiedziałem? Tutaj pozwól mi skopiować i wkleić dla ciebie: „To jedno z niewielu miejsc, w których nie zgadzam się z konwencją na tyle, aby się temu przeciwstawić”. Następnie wyjaśniam dlaczego.
Heather
2
Nie działam wbrew wytycznym „na wszystkie możliwe sposoby”. To hiperbola. Postępuję wbrew wytycznym w jeden, konkretny sposób, co potwierdza moje uzasadnienie. Jeśli chcesz się nie zgodzić, dobrze, podaj powody, dla których się nie zgadzasz; twoja hiperbola jest niepotrzebna i nie przyspiesza twojej pozycji.
Heather
1
Jeśli możliwa jest kolizja przestrzeni nazw, nie widzę problemu z dodawaniem Enum? To nie jest tak, że autor proponuje postfiksowanie wszystkich zmiennych z ich typem. Autor ma również znacznie silniejszy przypadek, biorąc pod uwagę powód, podczas gdy M $ daje zerowe uzasadnienie.
Jai Govindani,
7

Jeśli próbujesz napisać prosty, ale zabroniony kod, taki jak ten:

    public class Person
    {
        public enum Gender
        {
            Male,
            Female
        }
        //Won't compile: auto-property has same name as enum
        public Gender Gender { get; set; }  
    }

Twoje opcje to:

  1. Zignoruj ​​zalecenie MS i użyj prefiksu lub sufiksu w nazwie wyliczenia:

    public class Person
    {
        public enum GenderEnum
        {
            Male,
            Female
        }
        public GenderEnum Gender { get; set; }
    }
  2. Przenieś definicję wyliczenia poza klasę, najlepiej do innej klasy. Oto proste rozwiązanie powyższego:

    public class Characteristics
    {
        public enum Gender
        {
            Male,
            Female
        }
    }
    public class Person
    {
        public Characteristics.Gender Gender { get; set; }  
    }
MiloNC
źródło
2
Sytuacja hipotetyczna i niezbyt dobre rozwiązanie. Po co używać zagnieżdżonego, enuma następnie zagnieżdżać go w innej klasie, jeśli powoduje to problemy?
Gert Arnold,
1
W przypadku płci znacznie bardziej sensowne jest posiadanie nazwy właściwości as Genderi nazwy enum as Sex. Więc isac.Gender = Sex.Male..
nawfal
3
Nie jestem pewien, dlaczego ten facet jest krytykowany. Ta sytuacja jest uzasadniona i daleka od hipotetycznej. Gniazduje typy wyliczeniowe w języku C # z podobnych powodów, dla których można użyć klasy wewnętrznej w Javie ... ponieważ typ wewnętrzny jest używany tylko w zewnętrznym i nigdzie indziej, i ma sens tylko w kontekście zewnętrznym, a nie gdzie indziej. Z powodu ograniczeń kompilatora musisz wybrać jedno z wymienionych rozwiązań.
Nathan Pitman,
Będziesz musiał ustawić go gdzieś, zwykle poza klasą, a może podczas konstruowania klasy, w którym to przypadku musisz zdefiniować wyliczenie na zewnątrz, chyba że chcesz wysłać Person.Gender.Male, Płeć może dotyczyć więcej niż tylko ludzie, myślę, że nie zagnieżdżenie go jest najlepszym rozwiązaniem.
Jim Wolff,
2
Inną, prawdopodobnie lepszą opcją jest odpowiedź „Serge - appTranslator”.
Curtis Yallop
6

Najlepsza praktyka - używaj liczby pojedynczej. Masz listę przedmiotów, które tworzą Enum. Używanie pozycji na liście brzmi dziwnie, kiedy mówisz Versions.1_0. Bardziej sensowne jest stwierdzenie, Version.1_0ponieważ istnieje tylko jedna wersja 1_0.

Jeremy Cron
źródło
5

Spóźniamy się trochę ...

Istnieje ważna różnica między twoim pytaniem a tym , o którym wspomniałeś (które zadałem ;-):

Umieszczasz definicję wyliczenia poza klasą, co pozwala mieć taką samą nazwę dla wyliczenia i właściwości:

public enum EntityType { 
  Type1, Type2 
} 

public class SomeClass { 
  public EntityType EntityType {get; set;} // This is legal

}

W tym przypadku zastosowałbym się do wytycznych MS i użyłem pojedynczej nazwy dla wyliczenia (liczba mnoga dla flag). To chyba najłatwiejsze rozwiązanie.

Mój problem (w drugim pytaniu ) dotyczy tego, kiedy wyliczenie jest zdefiniowane w zakresie klasy, co uniemożliwia użycie właściwości nazwanej dokładnie po wyliczeniu.

Serge Wautier
źródło