Соглашение об именовании С# для свойства перечисления и соответствия

Я часто обнаруживаю, что реализую класс, поддерживающий какое-то собственное свойство состояния как перечисление: у меня есть свойство перечисления статуса и ОДНОГО статуса типа 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 применим к Car только потому, что не имеет смысла объявлять enum вне класса.

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

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

EDIT: Филип Экберг предлагает отличное обходное решение IMO для конкретного случая "Статус". Тем не менее, мне было бы интересно прочитать о решениях, где имя enum/property отличается, как в ответе Майкла Превеки.

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

Ответ 1

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

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

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

State (enum called States) - это вокатив, "Статус" - это именное имя существительного, что английский, как и большинство нашего языка, поглощен латинским языком. Вокатив - это то, что вы называете существительным для его состояния, а номинативный - предметом глагола.

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

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;

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

Ответ 2

Определение "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 =====

}

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

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

Пример. Состояние автомобиля находится в состоянии запуска, состояния остановки и т.д.

То, что вы хотите получить во втором примере, выглядит следующим образом:

myDataReader.Type = DataReader.Database.OleDb

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

Однако, перечисление было бы повторно использовано в вашем пространстве System.Data и в том, что все шаблоны.

Другим примером для поиска с типом является "Animal", где Type определяет Species.

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

        public Type Species{ get; set; }

    }

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

Ответ 3

Я думаю, что настоящая проблема заключается в том, что статус перечисления инкапсулирован в ваш класс, так что 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;}
}

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

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

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

Таким образом, я, вероятно, просто переименую его как:

public enum CarStatus
{...}

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

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

Ответ 4

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

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

Ответ 5

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

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

  public StatusEnum Status { get; set; }

}

Ответ 6

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

Ответ 7

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

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

Ответ 8

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