Соглашение об именовании в C # для перечисления и соответствующего свойства - PullRequest
88 голосов
/ 30 января 2009

Я часто обнаруживаю, что реализую класс, поддерживающий какое-то собственное свойство status в качестве enum: у меня есть enum Status и свойство ONE Status типа Status. Как мне решить этот конфликт имен?

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, поэтому не имеет смысла объявлять enum вне класса.

Какое соглашение об именах вы используете в этом случае?

NB. Этот вопрос частично обсуждался в комментариях к ответу на этот вопрос . Поскольку это был не основной вопрос, он не получил особого внимания.

РЕДАКТИРОВАТЬ: Филип Экберг предлагает IMO отличный обходной путь для конкретного случая «Статус». Тем не менее, мне было бы интересно прочитать о решениях, в которых имя перечисления / свойства отличается, как в answer .

Майкла Превецки.

EDIT2 (май 2010 г.): Мое любимое решение состоит в том, чтобы использовать имя типа enum во множественном числе, как предложено Крисом С. Согласно руководствам MS, это следует использовать только для перечислений флагов. Но мне это нравится все больше и больше. Теперь я использую его и для обычных перечислений.

Ответы [ 8 ]

34 голосов
/ 30 января 2009

Определение «Выкл.», «Запуск» и «Перемещение» - это то, что я бы назвал «Состояние». И когда вы намекаете, что используете «Состояние», это ваш «Статус». Так!

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 =====

}

Вы действительно должны видеть, что есть различия между перечислениями и перечислениями, верно? Но когда вы создаете фреймворк или говорите об архитектуре, вам нужно сосредоточиться на сходстве, давайте найдем их:

Когда что-то устанавливается в состояние, оно определяется как состояние «вещей»

Пример. Состояние автомобиля в рабочем состоянии, остановленном состоянии и т. Д.

Во втором примере вы хотите получить что-то вроде этого:

myDataReader.Type = DataReader.Database.OleDb

Вы можете подумать, что это говорит против того, что я проповедовал другим, что вам нужно следовать стандарту. Но вы следуете стандарту! Sql-case также является частным случаем и поэтому требует определенного решения.

Тем не менее, enum будет многократно использоваться в вашем System.Data пространстве, и именно в этом и заключается паттерн.

Другим случаем, который нужно рассмотреть с помощью «Типа», является «Животное», где Тип определяет Виды.

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

        public Type Species{ get; set; }

    }

Это следующий шаблон, вам не нужно специально «знать» объект для этого, и вы не указываете «AnimalType» или «DataReaderType», вы можете повторно использовать перечисления в выбранном вами пространстве имен.

30 голосов
/ 31 января 2009

Я добавлю 1 евро к обсуждению, но, вероятно, ничего нового не добавлю.

Очевидное решение - вывести Status из вложенного Enum. Большинство перечислений .NET (за исключением, возможно, некоторых в пространстве имен Windows.Forms) не являются вложенными, и это раздражает использование для разработчика, использующего ваш API, с префиксом имени класса.

Одна вещь, которая не была упомянута , это то, что перечисления флагов в соответствии с руководящими принципами MSDN должны быть множественными существительными , которые вы, вероятно, уже знаете (Status - это простое перечисление, поэтому существительные в единственном числе должны использоваться).

Государство (enum называется States) - это прилагательное, а «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;

На самом деле этого никогда не происходит, поскольку они реализованы в виде драйверов и цепочки наследования вместо использования перечислений, поэтому строка выше не выглядит естественной.

9 голосов
/ 30 января 2009

Я думаю, что настоящая проблема здесь в том, что enum Status инкапсулирован в вашем классе, так что Car.Status неоднозначно как для свойства Status, так и для перечисления Status

Еще лучше, поместите свой enum вне класса:

public enum Status
{
    Off,
    Starting,
    Moving
}

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

UPDATE

В связи с комментариями ниже, я объясню мой дизайн выше.

Я тот, кто не верит, что перечисления, классы или любые другие объекты должны находиться внутри другого класса, если только он не будет полностью закрытым в этом классе. Возьмите приведенный выше пример, например:

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

Хотя некоторые комментаторы утверждают, что Status не имеет никакого значения за пределами класса Car, тот факт, что вы устанавливаете свойство public , означает, что существуют другие части программы, которые будет использовать это перечисление:

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

И , что для меня - это запах кода. Если я собираюсь посмотреть на этот статус вне из Car, я мог бы также определить его вне .

Поэтому я, вероятно, просто переименую его в:

public enum CarStatus
{...}

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

Однако, если это перечисление будет использоваться в пределах и только в пределах класса автомобиля, тогда я могу объявить перечисление там.

4 голосов
/ 29 сентября 2013

Будь прокляты ненавистники венгерской нотации и ее вариантов. Я использую соглашение суффиксов перечислений с - ждать его - Enum. Следовательно, у меня никогда не возникает проблем, которые вы описываете, тратите время на размышления о том, как их назвать, а код удобен для чтения и информативен при загрузке.

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

  public StatusEnum Status { get; set; }

}
4 голосов
/ 08 сентября 2009

Я знаю, что мое предложение идет вразрез с соглашениями об именах .NET, но я лично префикс enum с 'E', а флаги enum с 'F' (аналогично тому, как мы префиксируем интерфейсы с 'I'). Я действительно не понимаю, почему это не конвенция. Enums / Flags - это особый случай, такой как Interfaces, который никогда не изменит своего типа. Мало того, что он дает понять, что это такое, очень просто ввести intellisense, поскольку префикс будет фильтровать большинство других типов / переменных / и т. Д., И у вас не будет этих конфликтов имен.

И это также решило бы другую проблему, когда для примеров в WPF они используют статические классы, такие как enums (например, FontWeights), которые имеют предопределенные экземпляры типов, но вы не узнаете, если не будете искать их. Если бы они просто добавили им префикс «E», все, что вам нужно было бы сделать, это набрать символ, чтобы найти эти специальные статические классы.

2 голосов
/ 30 января 2009

Я бы изменил имя свойства на что-то вроде «CurrentStatus». Быстрая легкая:)

1 голос
/ 31 августа 2011

Я предлагаю добавить «Option» к имени типа (или Flag, если он содержит битовые флаги), то есть тип - Car.StatusOption, а свойство - Car.Status.

По сравнению с множественным числом это позволяет избежать коллизий именования при создании коллекций типа enum, где обычно требуется использовать множественное значение свойство , а не enum type .

0 голосов
/ 30 января 2009

Я обычно добавляю префиксы к перечислениям, например CarStatus. Я предполагаю, что все зависит от команды, с которой вы работаете (если у них есть какие-либо правила / процессы для такого рода вещей) и использования объектов. Просто мои 2 цента (:

...