Я часто реализую класс, поддерживающий какое-то собственное свойство статуса в виде перечисления: у меня есть перечисление Status и ОДНО свойство 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, поэтому нет смысла объявлять перечисление вне класса.
Какое соглашение об именах вы используете в этом случае?
NB: Этот вопрос частично обсуждался в комментариях к ответу на этот вопрос . Поскольку это не было главным вопрос, он не получил особого внимания.
РЕДАКТИРОВАТЬ: Филип Экберг предлагает отличный обходной путь IMO для конкретного случая «Статус». Тем не менее , я бы интересно читать о решениях , где имя перечислений / собственность отличается, как и в Майкла Prewecki в ответ .
EDIT2 (май 2010 г.): Мое любимое решение - использовать множественное число для имени типа перечисления, как было предложено Крисом С. Согласно рекомендациям MS, это следует использовать только для перечислений флагов. Но мне это нравится все больше и больше. Теперь я использую его и для обычных перечислений.
источник
Ответы:
Я добавлю к обсуждению свой 1 евро, но это, вероятно, не добавит ничего нового.
Очевидное решение - переместить Status из вложенного Enum. Большинство перечислений .NET (за исключением, возможно, некоторых в пространстве имен Windows.Forms) не вложены, и разработчику, использующему ваш API, неудобно использовать префикс имени класса.
Одна вещь, о которой не упоминалось, - это то, что перечисления флагов в соответствии с рекомендациями MSDN должны быть существительными во множественном числе, которые вы, вероятно, уже знаете (Статус - это простое перечисление, поэтому следует использовать существительные в единственном числе).
State (перечисление States) - это звательный падеж, «Status» - именительный падеж существительного, которое английский язык, как и большая часть нашего языка, заимствовал из латыни. Звительный падеж - это то, что вы называете существительным в зависимости от его состояния, а именительный падеж - это подлежащее глагола.
Другими словами, когда машина движется , это глагол - движение - это ее статус. Но машина не трогается, а двигатель. И он не запускается, двигатель запускается (вы, вероятно, выбрали здесь пример, так что это может быть неуместно).
public class Car { VehicleState _vehicleState= VehicleState.Stationary; public VehicleState VehicleState { get { return _vehicleState; } set { _vehicleState = value; DoSomething(); } } } public enum VehicleState { Stationary, Idle, Moving }
Состояние - такое обобщенное существительное, не лучше ли описать, к какому состоянию оно относится? Как я сделал выше
Пример типа также, на мой взгляд, относится не к типу читателя, а к его базе данных. Я бы предпочел, чтобы вы описывали продукт базы данных читателя, который не обязательно имеет отношение к типу читателя (например, тип читателя может быть только прямым, кешированным и т. Д.). Так
На самом деле этого никогда не происходит, поскольку они реализованы в виде драйверов и цепочки наследования вместо использования перечислений, поэтому строка выше выглядит неестественно.
источник
public class EngineState
должен бытьpublic enum EngineState
в этом примере, верно?Определение «Выкл.», «Запуск» и «Движение» - это то, что я бы назвал «Состояние». И когда вы намекаете, что используете «Состояние», это ваш «Статус». Так!
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 ===== }
Вам действительно нужно увидеть разницу между перечислениями и перечислениями, верно? Но когда вы создаете фреймворк или говорите об архитектуре, вам нужно сосредоточиться на сходствах, давайте найдем их:
Когда что-то установлено в состояние, это определяется как статус "вещи".
Пример: Автомобиль находится в состоянии "Работа", "Остановлен" и т. Д.
Во втором примере вы хотите добиться примерно следующего:
Вы можете подумать, что это противоречит тому, о чем я проповедовал другим, что вам нужно следовать стандарту. Но вы следуете стандарту! Sql-case также является частным случаем и поэтому требует определенного решения.
Однако перечисление можно будет повторно использовать в вашем
System.Data
пространстве, и в этом суть шаблонов.Другой случай, который следует рассмотреть с «Типом», - это «Животное», где Тип определяет Вид.
public class Animal { public enum Type { Mammal, Reptile, JonSkeet } public Type Species{ get; set; } }
Это следует шаблону, вам не нужно специально «знать» для этого Object, и вы не указываете «AnimalType» или «DataReaderType», вы можете повторно использовать перечисления в выбранном вами пространстве имен.
источник
Я думаю, что настоящая проблема здесь в том, что статус перечисления инкапсулирован внутри вашего класса, поэтому это
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; } }
Однако, если это перечисление будет использоваться внутри и только внутри автомобильного класса, я вполне могу объявить перечисление там.
источник
OR
иCR
. Оба имеют свой собственный набор состояний, поэтому нельзя определять их вне их собственной области.Я знаю, что мое предложение идет вразрез с соглашениями об именах .NET, но я лично префикс перечислений с помощью «E» и флаги перечисления с помощью «F» (аналогично тому, как мы префикс интерфейсов с помощью «I»). Я действительно не понимаю, почему это не конвенция. Перечисления / флаги - это особый случай, подобный интерфейсам, которые никогда не меняют свой тип. Он не только проясняет, что это такое, но и очень легко вводить intellisense, поскольку префикс будет фильтровать большинство других типов / переменных / и т. Д., И у вас не будет этих конфликтов имен.
И это также решит другую проблему, когда для примеров в WPF они используют статические классы, такие как перечисления (например, FontWeights), которые имеют предварительно определенные экземпляры типов, но вы не узнаете, если не будете искать его. Если бы они просто поставили перед ними префикс «E», все, что вам нужно было бы сделать, это ввести символ, чтобы найти эти специальные статические классы.
источник
Будь прокляты ненавистники венгерской нотации и ее вариантов. Я использую соглашение о добавлении суффиксов к перечислениям - подождите -
Enum
. Следовательно, у меня никогда не возникает проблема, которую вы описываете, я трачу время на беспокойство о том, как их называть, а код читабелен и информативен для загрузки.public class Car { public enum StatusEnum { Off, Starting, Moving }; public StatusEnum Status { get; set; } }
источник
Я бы изменил имя свойства на что-то вроде CurrentStatus. Быстро и легко :)
источник
Я предлагаю добавить «Option» к имени типа (или Flag, если он содержит битовые флаги), т.е. тип - Car.StatusOption, а свойство - Car.Status.
По сравнению с множественным числом, это позволяет избежать конфликтов имен при создании коллекций типа enum, где вы обычно хотите использовать множественное число для свойства коллекции , а не для типа enum .
источник
Обычно я использую префикс для перечислений, например CarStatus. Я полагаю, все зависит от команды, с которой вы работаете (есть ли у них какие-либо правила / процессы для такого рода вещей) и использования объектов. Только мои 2 цента (:
источник