打开按位枚举

时间:2017-02-27 10:54:11

标签: powershell

我有一个获取数据的函数,根据一组用户指定的参数对其进行验证,如果它是正确的则输出,并且基于该操作,它可以正常工作。作为该功能的进一步发展,我试图转向“标志”的按位枚举。但是不能像我想的那样让它工作。

我想切换枚举并运行所有可能的匹配'但是只有在价值上只有一个直接匹配的情况下我才会得到匹配。 IE浏览器。当值为1时,它会运行案例' Milk'但如果该值为3,则不会运行' Milk'和面包'案件...我有点假设它试图运行牛奶,面包'情况下。

有没有简单的方法让我无法看到这个? ><

[Flags()] enum Breakfast {

    Nothing = 0
    Milk = 1
    Bread = 2
    Egg = 4
    Bacon = 8
}

$BreakfastFlag = 3


Switch ([Breakfast]$BreakfastFlag){

    Nothing {
    Write-Host "No breakfast was selected" -ForegroundColor White -BackgroundColor Red
    } 

    Milk {
    Write-Host "Milk was selected!" -ForegroundColor White -BackgroundColor DarkGreen
    }

    Bread {
    Write-Host "Bread was selected!" -ForegroundColor White -BackgroundColor DarkGreen
    }

    Egg {
    Write-Host "Egg was selected!" -ForegroundColor White -BackgroundColor DarkGreen
    }

    Bacon {
    Write-Host "Bacon was selected!" -ForegroundColor White -BackgroundColor DarkGreen
    }

}

2 个答案:

答案 0 :(得分:5)

另一种变体:

<div>
  <ul>
    <li>asdasd</li>
    <li>dhgfhgfh</li>
  </ul>
</div>

输出:

[Flags()] enum Breakfast {
    Nothing = 0
    Milk = 1
    Bread = 2
    Egg = 4
    Bacon = 8
}

$BreakfastFlag = 3

Switch ([Breakfast]$BreakfastFlag)
{
    Nothing {
        Write-Host "No breakfast was selected" -ForegroundColor White -BackgroundColor Red
    }

    { $_ -band [Breakfast]::Milk } {
        Write-Host "Milk was selected!" -ForegroundColor White -BackgroundColor DarkGreen
    }

    { $_ -band [Breakfast]::Bread } {
        Write-Host "Bread was selected!" -ForegroundColor White -BackgroundColor DarkGreen
    }

    { $_ -band [Breakfast]::Egg } {
        Write-Host "Egg was selected!" -ForegroundColor White -BackgroundColor DarkGreen
    }

    { $_ -band [Breakfast]::Bacon } {
        Write-Host "Bacon was selected!" -ForegroundColor White -BackgroundColor DarkGreen
    }
}

答案 1 :(得分:3)

如果简洁是目标,请创建一个辅助函数,接受带有键的哈希表作为标志和值的文本名称,包括脚本块:

function Switch-Flag($value, [hashtable]$switchboard) {
    $type = $value.GetType()
    $intValue = $value.value__
    $parsed = New-Object $type
    foreach ($e in $switchboard.GetEnumerator()) {
        $key = $e.name
        if ($key -is $type) {
            $r = $key.value__
        } elseif ($key -is [int]) {
            $r = $key
        } elseif ($type::TryParse($key, [ref]$parsed)) {
            $r = $parsed.value__
        } else {
            continue
        }
        if (($intValue -band $r) -eq $r) {
            if ($e.value -is [ScriptBlock]) {
                $e.value.Invoke()
            } else {
                $e.value
            }
        }
    }
}

用法示例1,简化:

[Breakfast]$flag = 3
Switch-Flag $flag @{
    Milk =  { Write-Host liquid }
    Bread = { Write-Host crunchy }
}

用法示例2,确保选择顺序:

$flag = 3
Switch-Flag ([Breakfast]$flag) ([ordered]@{
    Milk =  'liquid'
    Bread = 'crunchy'
})

用法示例3,使用enum作为键:

[Breakfast]$flag = 3
Switch-Flag $flag @{
    ([Breakfast]::Milk) =  { $milk++ }
    ([Breakfast]::Bread) = { $bread++ }
}

P.S。这比使用另一个答案中显示的-band表达式慢了10倍(180微秒对18微秒),因为显然PowerShell足够智能cache the expressions并且它还在本地范围内运行表达式scriptblocks,即,如果我理解正确的话,它不会在切换表达式的情况下创建新的范围。