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

Welcome Forums General PowerShell Q&A Why can't my enum values be specified as conditions for switch statement?

This topic contains 4 replies, has 3 voices, and was last updated by

js
 
Participant
2 months, 4 weeks ago.

  • Author
    Posts
  • #108784

    Participant
    Points: 0
    Rank: Member

    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

  • #108793

    Moderator
    Points: 49
    Team Member
    Rank: Member

    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 }
            }
    
  • #108797
    js

    Participant
    Points: 202
    Helping Hand
    Rank: Participant

    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
    
  • #108815

    Participant
    Points: 0
    Rank: Member

    AlexWjs, 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).

  • #108851
    js

    Participant
    Points: 202
    Helping Hand
    Rank: Participant

    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: https://kevinmarquette.github.io/2018-01-12-Powershell-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
    

You must be logged in to reply to this topic.