C#执行switch语句中的所有情况

RMo*_*med 5 c# loops case switch-statement

我有一个如下所示的switch语句:

switch(task)
    {
        case 1:
            print();
            break;
        case 2:
            save();
            break;
        case 3:
            sendmail();
            break;
    }
Run Code Online (Sandbox Code Playgroud)

我需要一种方法来执行所有情况,这意味着如果任务是(全部)我想打印,保存和发送邮件.是否可以在给定的情况下使用一些修改我知道,我可以如下:

case All:
    print();
    save();
    sendmail();
    break;
Run Code Online (Sandbox Code Playgroud)

但正如我所说,我想知道,如果在switch语句中有一种方法可以执行所有情况.提前致谢

Jam*_*ter 9

要回答您的实际问题:

如果在switch语句中有一种方法可以执行所有情况.

不是我能想到的干净方式.


我建议稍微改变模式,而不是制作task一个标志枚举

[Flags]
public enum TaskOptions 
{
    Print    = 1,
    Save     = 2,
    SendMail = 4,
    //Note that these numbers go up in powers of two
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以执行以下操作:

task = TaskOptions.Print | TaskOptions.Save;
if (task.HasFlag(TaskOptions.Print))
{ 
    print();
}
if (task.HasFlag(TaskOptions.Save))
{ 
    save();
}
if (task.HasFlag(TaskOptions.SendMail))
{ 
    sendMail();
}
Run Code Online (Sandbox Code Playgroud)

您不必再明确担心 all


然后,如果您想添加新选项

[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();
}
Run Code Online (Sandbox Code Playgroud)

Jaymee要求澄清|&

你能解释一下task = TaskOptions.Print |的语法吗?TaskOptions.Save.不知道在这里使用管道,我以为它是'或',但这里没有评价!?实际上,对于单个&符号也是如此 - 以前从未见过以这种方式使用它

这些是按位运算符.他们逐位比较两个数字并返回结果.

在我们的示例中,我们使用4个标志,每个标志由布尔值表示.布尔值可以用一位表示.

我们使用以下缩写:

Print = P
Save = S
SendMail = M
NewOption = N

8  4  2  1
N  M  S  P
Run Code Online (Sandbox Code Playgroud)

我用它task = TaskOptions.Print | TaskOptions.Save作为一个例子

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"
Run Code Online (Sandbox Code Playgroud)

当我有"3"并且我想知道它是否包含特定标志时,我&带着那个标志.

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!
Run Code Online (Sandbox Code Playgroud)

让我们为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"
Run Code Online (Sandbox Code Playgroud)

由David Arno编辑

要添加到这个答案,而不是有一系列的ifs,可以使用Dictionary和for循环:

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]();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `task.HasFlag(TaskOptions.NewOption)` (3认同)

Jon*_*nna 0

如您所知,在 C# 中,失败不会隐式发生,而是goto经过扩展以允许 case 标签成为目标标签,以便显式失败。

只需让您的“all”值与第一个标签匹配,然后继续下goto一个(如果这是该值):

switch(task)
{
  case 1: case 0;//I don't know what "all" is, so I'm using 0 here
    print();
    if (task == 0) goto case 2;
    break;
  case 2:
    save();
    if (task == 0) goto case 3;
    break;
  case 3:
    sendmail();
    break;
}
Run Code Online (Sandbox Code Playgroud)

  • 在我看来,这是一个可怕的语言功能 (3认同)
  • @JonHanna - Dijkstra 所说的有效性仍然有效。用“goto”控制流程是可怕的。 (2认同)