#c# #linq #enums
Вопрос:
У меня есть класс перечисления с именем AccountStatus с почти 20 значениями перечисления. И мне нужно выполнить некоторую операцию, если совпадают 10 перечислений. и выполните другую операцию, если все перечисления совпадают. Теперь мой я написал код следующим образом
public enum AccountStatus
{
Unknown ,
Pending,
Deleted,
Declined,
Deactivated,
Processing,
......
}
Мой образец, если условие
if(status == AccountStatus.Unknown || status == AccountStatus.Pending || status == AccountStatus.Declined
||status == AccountStatus.Hold|| status == AccountStatus.Stopped|| status == AccountStatus.Deferred
||status == AccountStatus.Rejected || status == AccountStatus.Waiting|| status == AccountStatus.Deleted)
{
// Perform Some operation.
}
Есть ли лучший способ избежать этих многих или условий?
Комментарии:
1. Пожалуйста, включите определение
AccountStatus
. Если в тестируемых значениях нет пробелов (и они не приписываются[Flags]
), вы можете выполнить тест диапазона (или, возможно, пару тестов диапазона, если есть 1 пробел).2. Согласовано с тестом диапазона, в противном случае, если это невозможно, вы можете использовать переключатель с выпадением первых 10 значений, а затем по умолчанию для остальных
Ответ №1:
Возможным решением было бы превратить проверку в операцию переключения:
switch (status)
{
case AccountStatus.Unknown:
case AccountStatus.Pending:
case AccountStatus.Declined:
case AccountStatus.Hold:
case AccountStatus.Stopped:
case AccountStatus.Deferred:
case AccountStatus.Rejected:
case AccountStatus.Waiting:
case AccountStatus.Deleted:
{
// Perform Some operation.
}
break;
}
Ответ №2:
Если ваши enum
проверки всегда проверяют эти значения, вы можете расположить их в нужном вам порядке. Перечисление на самом деле-это просто int
значение, и вы можете присваивать int
им значения по своему усмотрению. Таким образом, вы также можете сравнить an enum
с an int
.`
public enum AccountStatus {
Unknown = 0,
Pending = 1,
Declined = 2
// and so on
}
Значения, которые я там установил, совпадают со значениями по умолчанию, но вы можете увидеть, как вы можете использовать другие значения вместо значений по умолчанию.
Затем вы просто сравниваете, как обычно:
public static void Main() {
AccountStatus s = AccountStatus.Pending;
if (s <= AccountStatus.Pending) {
// Perform some operation
} else {
// Perform some other operation
}
}
Ответ №3:
Ответ Max Play с утверждением о большом переключателе хорош в своей простоте. Однако с ним невозможно работать, если у вас действительно много перечислений. Также очень сложно провести модульное тестирование, чтобы убедиться, что вы не забыли case
Если мне кажется, что если состояние учетной записи неизвестно / Ожидание / Отклонено / Ожидание / и т. Д. в этом статусе есть что-то общее. Эта общая вещь заставляет вас по-разному обрабатывать учетные записи с этими статусами: есть две «группы учетных записей».
Подумайте о том, чтобы стратегически пронумеровать свои перечисления, сделав их полями.
Я не знаю, что такого особенного в этих типах учетных записей, что к ним нужно относиться по-другому. Поэтому мне придется привести пример с перечислением типов автомобилей.
[Flage]
enum CarType
{
None = 0x00,
Gaz = 0x01,
Electric = 0x02,
FourWheelDrive = 0x04
AirConditioning = 0x08,
SunRoof = 0x10,
CruiseControl = 0x20,
... // etc
BMW1Series = Gaz,
BMW4Series = Gaz | AirConditioning,
BMW4x4 = Gaz | FourWheelDrive,
BMW4x4Executive = Gaz | FourWheelDrive | AirConditioning | CruiseControl,
TotoyataPrius = Gaz | Electric | Airconditioning | CruiseControl,
...
Теперь, чтобы узнать, нуждается ли автомобиль в обслуживании кондиционера во время регулярного технического обслуживания, вы можете воспользоваться большим переключателем, в котором у вас есть все известные модели автомобилей:
bool NeedsAirconditioningCheck(Car car)
{
switch (car.CarType)
{
case ToyotaPrius:
case BMW4x4Executive:
...
// etc, do this for all 1254 car models that have an airconditioning
return true;
default:
return false;
}
Используя флаги, это было бы намного проще:
bool NeedsAirconditioningCheck(Car car)
{
return (car.CarType amp; CarType.AirConditioning) == CarType.AirConditioning;
}
Другой пример: Автомобиль является гибридным, если он использует Газ и электричество:
bool IsHybrid(Car car)
{
CarType Hybrid = CarType.Gaz | Cartype.Electric;
return (car.Cartype amp; Hybrid) == Hybrid;
}
Преимущества:
- Эти процедуры не придется менять, если ваше перечисление будет дополнено новыми моделями автомобилей
- Эти процедуры не придется менять, если мы придумаем новую функцию. Например, если изобретена новая функция, подобная
KeepYourLane
этой, то, по-видимому, у всех существующих моделей автомобилей этой функции не было. Все старые типы карт менять не придется, только недавно добавленные. - Намного проще для понимания и визуальной проверки правильности метода
- Проще в модульном тестировании