Why can't my enum values be specified as conditions for switch statement?

Please see example below.

# CREATE ENUM WHOSE VALUES WILL BE USE AS PARAMETER OPTIONS
Add-Type -TypeDefinition @"
 public enum MyOptions {
  someLongLongOption1 = 1,
  someLongLongOption2 = 2,
  someLongLongOption3 = 3
 }
"@

# CREATE FUNCTION IN WHICH ANY VALUE OF ENUM IS USED AS PARAMETER OPTION
function Get-MyOption
{
 param
 (
  [Parameter(Mandatory=$true)]
  [MyOptions]$MyOption
 )
 # CHECK WHAT OPTION HAS BEEN SPECIFIED
 switch($MyOption)
 {
  [MyOptions]::someLongLongOption1{Write-Host "option 1"}
  default{Write-Host "some option other than option 1"}
 }
}

Not only “[MyOptions]::someLongLongOption1” is not recognized inside a “switch” statement as one of the conditionals (as soon as you type “::” the ISE does not list members of “[MyOptions]” enumeration as it should), the same “[MyOptions]::someLongLongOption1” value is actually recognized as conditional if put inside an “if” statement’s parentheses instead.

 

Now if you type “Get-MyOption -MyOption someLongLongOption1” the switch statement resolves to “default” and “some option other than option 1” is displayed. Why do “if” statements work correctly for such value checks but “switch” statement doesn’t? What changes do I need to make so that a “switch” statement works too?

 

Thanks

To fix it, you can just wrap it in curly brackets.

   switch ($MyOption) {
        {[MyOptions]::someLongLongOption1} {Write-Host "option 1"}
        default {Write-Host "some option other than option 1"}
    }

If you look at the helpfile

get-help about_switch

It shows you the syntax, the expression should be in curly brackets { }

 SYNTAX
    The complete Switch statement syntax is as follows:

        switch [-regex|-wildcard|-exact][-casesensitive] ()

    or

        switch [-regex|-wildcard|-exact][-casesensitive] -file filename

    followed by

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

You have to add some parentheses for some reason. You can also declare the enum this way. (There’s [flags()] enum too now.) Wish the windows were wider. The about_switch help could use an expression example.

enum MyOptions {
  someLongLongOption1 = 1
  someLongLongOption2 = 2
  someLongLongOption3 = 3
 }

$myoption =  [MyOptions]::someLongLongOption1

switch($MyOption) {
  ([MyOptions]::someLongLongOption1) {Write-Host 'option 1'}
  default                          {Write-Host 'some other'}
}

option 1

AlexW, js, thank you!

Using parentheses works but using curly brackets results in unexpected behavior (if you have “default” condition, previous to it condition–which is pre-last condition–always executes regardless of the value specified for the parameter during the function call).

I think you want to use parentheses. The curly braces seem to be for where-object like conditions. Here’s a very nice blog with examples, including enums with implied casting and implied string quoting: Powershell: Everything you ever wanted to know about the switch statement

enum MyOptions {
  someLongLongOption1 = 1
  someLongLongOption2 = 2
  someLongLongOption3 = 3
 }

$myoption = [MyOptions]::someLongLongOption3

switch($MyOption) {
  someLongLongOption1 {'option 1'}
  someLongLongOption2 {'option 2'}
  someLongLongOption3 {'option 3'}
  default             {'other'}
}

# output
option 3

Looks like you don’t have to quote strings:

$myoption = 'there'

switch($MyOption) {
  hi      {'option 1'}
  there   {'option 2'}
  default {'other'}
}

# output                                                                                                             
option 2

Flags enum example:

[flags()] enum MyOptions {
  someLongLongOption1 = 1
  someLongLongOption2 = 2
  someLongLongOption3 = 4
}

[MyOptions]7

# output
someLongLongOption1, someLongLongOption2, someLongLongOption3