Reputation: 11
I have an enum class named AccountStatus with nearly 20 enum values. And I need to perform some operation if 10 enums are matched. and perform another operation if remain enums matched. Now My I have written code as follows
public enum AccountStatus
{
Unknown ,
Pending,
Deleted,
Declined,
Deactivated,
Processing,
......
}
My Sample if condition is
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.
}
Is there a better way to avoid those many or conditions?
Upvotes: 0
Views: 1006
Reputation: 30464
The answer of Max Play, with the big Switch Case statement is good in its simplicity. However, it is impossible to work with it, if you do have a lot of enums. It is also very difficult to unit test it, to make sure that you haven't forgotten a case
If seems to me, that if the AccountStatus is Unknown / Pending / Declined / Waiting / etc. there is something common about the status. This common thing makes that you want to process Accounts with these statusses differently: there are two "groups of accounts"
Consider to number your enums strategically, making it fields.
I don't know what is so special about these AccountTypes that they need to be treated differently. Therefore I'll have to give an example with an enum of Car types.
[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,
...
Now to know if a Car needs to have its Airconditioning serviced during its regular maintenance, you could do the big switch case where you have all known models of Cars:
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;
}
Using Flags, this would be way more easier:
bool NeedsAirconditioningCheck(Car car)
{
return (car.CarType & CarType.AirConditioning) == CarType.AirConditioning;
}
Another example: a Car is Hybrid if it uses Gaz and Electricity:
bool IsHybrid(Car car)
{
CarType Hybrid = CarType.Gaz | Cartype.Electric;
return (car.Cartype & Hybrid) == Hybrid;
}
Advantages:
KeepYourLane
is invented, then apparently all existing car models didn't have this feature. All old CarTypes won't have to change, only the newly added ones.Upvotes: 0
Reputation: 4428
If your enum
checks always checks for these values you could put them in the order you want them. An enum is really just an int
value, and you can assign int
values to them as you see fit. As such, you can also compare an enum
to an int
.`
public enum AccountStatus {
Unknown = 0,
Pending = 1,
Declined = 2
// and so on
}
The values I set there are the same as default values, but you can see how you can use other values instead of the default ones.
Then you just compare as you would normally:
public static void Main() {
AccountStatus s = AccountStatus.Pending;
if (s <= AccountStatus.Pending) {
// Perform some operation
} else {
// Perform some other operation
}
}
Upvotes: 1
Reputation: 4037
A possible solution would be to change the check into a switch operation:
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;
}
Upvotes: 3