I have a switch statement like the following :
switch(task)
{
case 1:
print();
break;
case 2:
save();
break;
case 3:
sendmail();
break;
}
I need a way to execute all cases, which means if task is (All) I want to print, save and send mail. Is it doable using some modification on the given case I know that, I can make it as follow:
case All:
print();
save();
sendmail();
break;
But as I said I want to know, if there is a way in switch statement to execute all cases. Thanks in advance
To answer your actual question:
if there is a way in switch statement to execute all cases.
Not a clean way that I can think of.
I would suggest changing the pattern a bit and instead making task
a flag enum
[Flags]
public enum TaskOptions
{
Print = 1,
Save = 2,
SendMail = 4,
//Note that these numbers go up in powers of two
}
You can then do something like the following:
task = TaskOptions.Print | TaskOptions.Save;
if (task.HasFlag(TaskOptions.Print))
{
print();
}
if (task.HasFlag(TaskOptions.Save))
{
save();
}
if (task.HasFlag(TaskOptions.SendMail))
{
sendMail();
}
You no longer have to worry explicitly about all
Then if you wanted to add a new option
[Flags]
public enum TaskOptions
{
Print = 1,
Save = 2,
SendMail = 4,
NewOption = 8,
}
task = TaskOptions.Print | TaskOptions.Save;
if (task.HasFlag(TaskOptions.Print))
{
print();
}
if (task.HasFlag(TaskOptions.Save))
{
save();
}
if (task.HasFlag(TaskOptions.SendMail))
{
sendMail();
}
if (task.HasFlag(TaskOptions.NewOption))
{
newOption();
}
Jaymee asked for clarification about the |
and the &
Can you please explain the syntax of task = TaskOptions.Print | TaskOptions.Save. Not sure on the use of the pipe here, I thought it was 'or', but there's no evaluation here!? In fact, same for the single ampersand - never seen it used in that way before
These are bitwise operators. They compare two numbers, bit by bit and return a result.
In our example, we're using 4 flags, each represented by a boolean. A boolean can be represented by one bit.
Let's use the following abbreviations:
Print = P
Save = S
SendMail = M
NewOption = N
8 4 2 1
N M S P
I used task = TaskOptions.Print | TaskOptions.Save
as an example
0 0 0 1 P is declared as 1 in the enum.
0 0 1 0 S is declared as 2 in the enum.
==========
0 0 1 1 < I've "or'd" these numbers together. They now represent Print AND Save as one option. The number "3" (binary 0011) is equivalent to "print and save"
When I have "3" and I want to know if it contains a specific flag, I &
with that flag.
N M S P
0 0 1 1 //This is P & S
0 0 0 1 //And we want to check if it has "P"
==========
0 0 0 1 < this returns non-zero. it contains the flag!
Let's do the same thing for N
N M S P
0 0 1 1 //This is P & S
1 0 0 0 //And we want to check if it has "N"
==========
0 0 0 0 < this returns zero. This state doesn't contain "N"
Edit by David Arno
To add to this answer, rather than having a series of if
s, a Dictionary and for loop can be used instead:
private readonly Dictionary<TaskOptions, Action> actions =
new Dictionary<TaskOptions, Action>
{
{ TaskOptions.Print, Print },
{ TaskOptions.Save, Save },
{ TaskOptions.SendMail , SendMail }
};
...
var task = TaskOptions.Print | TaskOptions.Save;
foreach (var enumValue in Enum.GetValues(typeof(TaskOptions)).Cast<TaskOptions>())
{
if (task.HasFlag(enumValue))
{
actions[enumValue]();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With