Конвенція про іменування Енума - множина


267

Я задаю це запитання, незважаючи на те, що я прочитав подібне, але не зовсім те, що я хочу на C # імені конвенції для іменування та відповідності властивості

Я виявив, що я схильний називати переліки у множині, а потім 'використовувати' їх як однини, наприклад:

public enum EntityTypes {
  Type1, Type2
}

public class SomeClass {
  /*
    some codes
  */

  public EntityTypes EntityType {get; set;}

}

Звичайно, це працює, і це мій стиль, але чи може хтось знайти потенційну проблему з такою умовою? У мене є "потворне" найменування словом "Статус", хоча:

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

public class SomeClass {
  /*
    some codes
  */

  public OrderStatuses OrderStatus {get; set;}

}

Додаткова інформація: Можливо, моє питання було недостатньо зрозумілим. Мені часто доводиться довго думати, називаючи змінні моїх визначених типів enum. Я знаю найкращу практику, але це не допомагає полегшити роботу щодо іменування цих змінних.

Я не можу викрити всі свої властивості перерахунків (скажімо "Статус") як "MyStatus".

Моє запитання: Чи може хтось знайти потенційну проблему в моїй конвенції, описаній вище? НЕ про найкращу практику.

Перефразовуйте питання:

Ну, я думаю, я повинен поставити запитання таким чином: Чи може хтось викласти хороший загальний спосіб іменування типу enum таким, що при використанні іменування enum 'екземпляр' буде досить простим?


5
public enum OrderState ... - публічний замовленняState OrderStatus {get; set;}
Фрейзер

Відповіді:


333

Microsoft рекомендує використовувати однину для Enums, якщо не Enumпредставляє бітові поля (також використовуйте FlagsAttribute). Див. Розділ Перерахування типів переліку назв (підмножина Посібників з іменування Microsoft ).

Щоб відповісти на ваше роз'яснення, я не бачу нічого поганого ні в одному з наступних:

public enum OrderStatus { Pending, Fulfilled, Error };

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

або

public enum OrderStatus { Pending, Fulfilled, Error };

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

20
Так, це правильна відповідь. Ці вказівки використовуються в .Net Framework, наприклад enum DayOfWeek та прапори enum RegexOptions.
Олександр Цвітбаум

1
Так, це рекомендована практика, я вітаю це. Однак це не відповідає на моє запитання.
okw

1
@okw для подальшої деталізації, хоча це виглядає некрасиво, якщо вам потрібно одне значення з enum прапора, використовуйте форму сингулярного для поля / властивості / аргументу. Якщо ви підтримуєте його з декількома прапорами, використовуйте множину. Якщо ваш enum не є прапорцем enum, використовуйте однину для імені типу та поля / властивості / аргументів.
Джонатан Дікінсон

4
Ось посилання на .Net 4.0 версію посібника з конвенцій про іменування Microsoft, пов’язаного у відповіді.

1
@Thomas У мене ніколи не було проблем з цим, я не бачу, чому це не спрацює - не бачу контексту, де було б неоднозначно, чи є посилання на тип чи змінну. тобто OrderStatus == OrderStatus.Pendingвизнається змінною зліва, а потім перерахуванням праворуч
Джеймс Херлі

39

Я почав називати переліки в множині, але з тих пір змінився на однину. Здається, це має більше сенсу в контексті того, де вони використовуються.

enum Status { Unknown = 0, Incomplete, Ready }

Status myStatus = Status.Ready;

Порівняти з:

Statuses myStatus = Statuses.Ready;

Я вважаю, що особливість форми звучить природніше в контексті. Ми погоджуємось, що, оголошуючи перелік, який відбувається в одному місці, ми думаємо, що «це група судівників», але при використанні її, імовірно, у багатьох місцях, ми думаємо, що «це одна річ» .


6
Трохи пізня реакція (і, можливо, трохи поза темою), але: я б запропонував використовувати значення 0для невідомого значення, таким чином неініціалізована змінна за замовчуванням Unknown.
SvenL

Погоджено, @SvenL. Оновлений приклад відповідно.
Боб Кауфман

Невже ви дійсно покладете [Flags]атрибут на свій приклад? Не має сенсу щось мати статус "Неповний" та "Готовий". Якби у вас був enum [Flags]Steps { First, Second, Third }, чи справді ви назвете свою змінну completedStep?
Пакман

26

Ситуація ніколи насправді не стосується множини.

enumПоказує ознака чого - то або інше. Наведу приклад:

enum Humour
{
  Irony,
  Sarcasm,
  Slapstick,
  Nothing
}

Ви можете мати один тип, але спробуйте продумати його у множині, а не в множині:

Humour.Irony | Humour.Sarcasm

Швидше ніж

Humours { Irony, Sarcasm }

У вас є почуття гумору, у вас немає почуття гумору.


5
Ха-ха, ну програмісти не завжди граматично / політично коректні. У вашому випадку я, ймовірно, використовую "HumourTypes". Я думаю, погана звичка.
okw

Що робити, якщо я хочу шукати всіх людей, у яких є сенс сарказму АБО відчувають іронію, я б не передавав рутині пошуку екземпляр, Humoursщо містить Humours.Irony | Huomours.Sarcasm??
Чарльз Бретана

14

Загалом, рекомендація щодо найкращої практики є одниною, за винятком тих переліків, у яких прикріплений атрибут [Прапори] (і тому вони можуть містити бітові поля), які мають бути множинами.

Прочитавши ваше відредаговане запитання, я відчуваю, що ви можете подумати, що ім'я властивості чи ім’я змінної має відрізнятися від імені типу enum ... Це не так. Далі ідеально чудово ...

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

  public class Order
  {
      private Status stat;
      public Status Status
      { 
         get { return stat; }
         set { stat = value; }
      }
  }

Правда, я думаю, що мій метод - це «швидкий і ледачий» спосіб уникнути необхідності думати імена при використанні переліків.
okw

1
На підтвердження вашої відповіді: на MSDN, з Імена членів типу в розділі "Імена властивостей": ✓ ВАЖИТИ присвоєння властивості те саме ім'я, що і його тип. Приклад: public Color Color { get {...} set {...} }
DavidRR

10

Це одне з небагатьох місць, з якими я не згоден з конвенцією, достатньо, щоб піти проти неї. ТБХ, Я НЕ ХАЮ, що визначення перерахунку та його екземпляр можуть мати те саме ім’я. Я розміщую всі свої "Енуми" спеціально, тому що це дає зрозуміти, який це контекст у будь-якому використанні. IMO це робить код набагато читабельнішим.

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


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

Ніхто ніколи не буде плутати, що таке перерахунок і що є його примірником.


2
Я прийшов сюди шукати конвенцію про іменування, після того, як клас та енюм назвали тим самим - і хотіли мати "щось", щоб зробити це більш очевидним. Я думав про префіксування його "E" (очевидно для Enums), як ми приставку інтерфейсу "I", - але мені сподобалось ваше рішення Хізер! Хороший!!!
Скотт

1
З дизайнерських ліній Microsoft: "НЕ використовуйте суфікс" Enum "у назвах типів enum." docs.microsoft.com/en-us/dotnet/standard/design-guidelines/…
Thoryn Hawley

3
Можливо, ви пропустили ДУЖЕ ПЕРШЕ речення з того, що я сказав? Ось, дозвольте скопіювати і вставити його для вас: "Це одне з небагатьох місць, з якими я не згоден з умовою, достатньо, щоб піти проти цього". Потім я продовжую пояснювати, чому.
Хізер

2
Я не йду проти принципів "всіляко". Це гіпербола. Я суперечу вказівкам єдиним, конкретним способом, який підтримується міркуваннями, які я викладаю. Якщо ви хочете не погодитися, добре, перелічіть свої причини не погоджуючись; ваша гіпербола непотрібна і не просуває вашу позицію.
Хізер

1
Якщо можливе зіткнення простору імен, я не бачу проблем із додаванням Enum? Це не так, якби автор пропонує постфіксацію всіх vars з їх типом. Автор також має набагато більш вагомий випадок, враховуючи, що причина наводиться, тоді як M $ дає нульове обгрунтування.
Джай Говіндані

7

Якщо ви намагаєтесь писати прямо, але заборонений код на зразок цього:

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

Ваші варіанти:

  1. Ігноруйте рекомендації MS та використовуйте префікс або суфікс для назви enum:

    public class Person
    {
        public enum GenderEnum
        {
            Male,
            Female
        }
        public GenderEnum Gender { get; set; }
    }
  2. Перемістіть визначення enum поза класом, бажано, в інший клас. Ось просте рішення вищезазначеного:

    public class Characteristics
    {
        public enum Gender
        {
            Male,
            Female
        }
    }
    public class Person
    {
        public Characteristics.Gender Gender { get; set; }  
    }

2
Гіпотетична ситуація і не вдале рішення. Навіщо використовувати вкладене enumв першу чергу, а потім вкладати його ще в інший клас, якщо це спричиняє проблеми?
Герт Арнольд

1
У випадку гендеру набагато важливіше мати ім'я властивості як Genderі ім'я перерахування як Sex. Отже isac.Gender = Sex.Male..
nawfal

3
Я не впевнений, чому цього хлопця зволікають. Ця ситуація є законною та далеко не гіпотетичною. Один гніздовий тип enum в C # з аналогічних причин, що можна використовувати внутрішній клас на Java ... тому що внутрішній тип використовується лише зовнішньому і ніде більше, і має сенс лише в контексті зовнішнього, а не в іншому місці. І внаслідок обмежень компілятора вам доведеться вибрати одне із згаданих рішень.
Натан Пітман

Вам доведеться встановити його десь, як правило, поза класом, або, можливо, при конструюванні класу, і тоді вам потрібно, щоб enum був визначений зовні, якщо ви не хочете відправити в Person.Gender.Male, гендер може застосувати більше ніж просто люди, я думаю, що не мати це вкладене є найкращим рішенням у будь-якому випадку.
Jim Wolff

2
Ще один, можливо, кращий варіант - відповідь від "Serge - appTranslator".
Кертіс Яллоп

6

Краща практика - використовувати однину. У вас є список предметів, які складають Enum. Використання елемента в списку звучить дивно, коли ви говорите Versions.1_0. Це має сенс сказати, Version.1_0оскільки існує лише одна версія 1_0.


5

Заходить трохи пізно ...

Існує важлива різниця між вашим запитанням і тим, яке ви згадуєте (яке я запитав ;-):

Ви ставите визначення enum з класу, що дозволяє вам мати однакове ім'я для enum та властивості:

public enum EntityType { 
  Type1, Type2 
} 

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

}

У цьому випадку я б дотримувався правил MS та використовував одне ім’я для enum (множина для прапорів). Це, швидше за все, найпростіше рішення.

Моя проблема (в іншому питанні ) полягає в тому, коли enum визначається в області класу, що перешкоджає використанню властивості, названої саме після enum.


0

З іншого потоку C # називає умовою для перерахування властивостей і суміщення хтось вказав, що, на мою думку, є дуже хорошою ідеєю:

"Я знаю, що моя пропозиція суперечить конвенціям .NET іменування, але я особисто префікс перераховує" E "і прапор переписує з" F "(подібно до того, як ми префіксуємо інтерфейси" I ")."

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.