我有一个获取数据的函数,根据一组用户指定的参数对其进行验证,如果它是正确的则输出,并且基于该操作,它可以正常工作。作为该功能的进一步发展,我试图转向“标志”的按位枚举。但是不能像我想的那样让它工作。
我想切换枚举并运行所有可能的匹配'但是只有在价值上只有一个直接匹配的情况下我才会得到匹配。 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
}
}
答案 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,即,如果我理解正确的话,它不会在切换表达式的情况下创建新的范围。