在Switch语句中解析“case”常量没有意义

时间:2014-01-31 18:50:16

标签: powershell switch-statement

有人可以向我解释此代码中第二个switch语句的行为:

function weird()
{
    $l_ret= [System.Windows.Forms.DialogResult]::Abort
    "Begin Switch OK"
    switch( $l_ret )
    {
        ([System.Windows.Forms.DialogResult]::Abort)  { 'Abort'  }
        ([System.Windows.Forms.DialogResult]::Cancel) { 'Cancel' }
    }
    "End Switch OK"
    "Begin Switch BAD"
    switch( $l_ret )
    {
        [System.Windows.Forms.DialogResult]::Abort  { 'Abort'  }
        [System.Windows.Forms.DialogResult]::Cancel { 'Cancel' }
    }
    "End Switch BAD"
}

如果我调用weird,我会:

Begin Switch OK
Abort
End Switch OK
Begin Switch BAD
End Switch BAD

但我期望的是:

Begin Switch OK
Abort
End Switch OK
Begin Switch BAD
Abort
End Switch BAD

[编辑更清楚我要问的是什么] 换句话说,在解析它不识别类型枚举常量的情况值时,它是什么样的解析模式???

感谢。

编辑:Keith在下面的检查答案中的倒数第二个评论是“答案”。他的其他评论很有用。感谢。

1 个答案:

答案 0 :(得分:0)

正如Bruce所提到的,你需要在坏开关中的类型说明符周围添加一些parens,例如:

function weird()
{
    $l_ret= [System.Windows.Forms.DialogResult]::Abort
    "Begin Switch OK"
    switch( $l_ret )
    {
        ([System.Windows.Forms.DialogResult]::Abort)  { 'Abort'  }
        ([System.Windows.Forms.DialogResult]::Cancel) { 'Cancel' }
    }
    "End Switch OK"
    "Begin Switch BAD"
    switch( $l_ret )
    {
        ([System.Windows.Forms.DialogResult]::Abort)  { 'Abort'  }
        ([System.Windows.Forms.DialogResult]::Cancel) { 'Cancel' }
    }
    "End Switch BAD"
}

否则PowerShell只是将该信息解释为字符串而不是类型说明符。它以这种方式运行,因此开启简单的字符串令牌很简单,例如:

$var = "bar"
switch ($var) {
    foo { "foo" }
    bar { "bar" }
}

switch语句通常也可以对文字值而不是表达式进行操作。 PowerShell允许您使用表达式,但通常使用scriptblock {...}指定表达式。似乎PowerShell也接受了parens(将表达式转换为文字以匹配)。这与PowerShell的命令解析模式最为一致。

FWIW我会注意到关于开关的帮助有点误导:

followed by
   {
       "string"|number|variable|{ expression } { statementlist }
       default { statementlist }
   }

这似乎表明,当字符串文字显然不需要时,必须引用字符串文字。好吧,除非字符串包含空格或其他标点符号,例如{;等。

BTW这个缩短的版本有效:

    switch( $l_ret )
    {
        Abort  { 'Abort'  }
        Cancel { 'Cancel' }
    }

如果知道枚举类型是什么,那么PowerShell知道如何将枚举的字段名强制转换为枚举类型。不幸的是,PowerShell无法做到这一点,至少在这种情况下,对于完全指定的名称。