在switch语句中更改赋值器

时间:2012-10-24 21:48:56

标签: powershell switch-statement

有没有办法,在'switch'中修改你正在评估的变量,并让它改变匹配?

$var = "a"
switch ($var){

    "a" {Write-Host "1st match for 'a'"}
    "b" {Write-Host "1st match for 'b'"}
    "a" {Write-Host "2nd match for 'a'"; $var = "b" ; continue}
    "b" {Write-Host "2st match for 'b'"}
}

我希望能够得到以上内容:

'a'的第一场比赛 'a'的第二场比赛 'b'的第二场比赛

$Destination = "vmstores:\vcsa@443\Training\Local-B\David" #is a param of my function, which could be a bunch of different types of object.

$DestinationType = $Destination.GetType().Name

    switch ($DestinationType){
        "String" {
            if ((Test-Path $Destination) -eq $true){
                if ((Get-Item $Destination).GetType().Name -eq "DatastoreFolderImpl"){
                    $DestinationType = "DatastoreFolderImpl"
                    if ((Test-Path $Destination.Insert($Destination.Length,"\").Insert(($Destination.Length)+1,$SourceVMXShort)) -eq $true){
                    Write-Warning "Destination File exists..."
                    $DestinationExists = $true
                    }
                }
                elseif ((Get-Item $Destination).GetType().Name -eq "DatastoreFileImpl"){
                    $DestinationType = "DatastoreFileImpl"
                    Write-Warning "Destination File exists..."
                    $DestinationExists = $true
                }
            }
             ; continue
        }
        "DirectoryInfo" {
            if ((Test-Path $Destination.Insert($Destination.Length,"\").Insert(($Destination.Length)+1,$SourceVMXShort)) -eq $true){
                Write-Warning "Destination File exists..."
                $DestinationExists = $true
            }
            ; break
        }
        "FileInfo" {
            if ((Test-Path $Destination) -eq $true){
                Write-Warning "Destination File exists..."
                $DestinationExists = $true
            }
            ; break
        }
        "DatastoreFileImpl" {
            if ((Test-Path $Destination) -eq $true){
                Write-Warning "Destination File exists..."
                $DestinationExists = $true
            }
            ; break
        }
        "DatastoreFolderImpl" {
            if ((Test-Path $Destination.Insert($Destination.Length,"\").Insert(($Destination.Length)+1,$SourceVMXShort)) -eq $true){
                Write-Warning "Destination File exists..."
                $DestinationExists = $true
            }
            ; break
        }
        "NasDatastoreImpl" {
            New-PSDrive -Name "DestMount" -Root \ -PSProvider VimDatastore -Datastore $Destination | Out-Null
            if ((Test-Path ("DestMount:").insert(10,"\").Insert(11,$SourceVMXShort)) -eq $true){
                Write-Warning "Destination File exists..."
                $DestinationExists = $true
            }
            $Destination = ("DestMount:").insert(10,"\")
            ; break
        }
        "VMFSDatastoreImpl" {
            New-PSDrive -Name "DestMount" -Root \ -PSProvider VimDatastore -Datastore $Destination | Out-Null
            if ((Test-Path ("DestMount:").insert(10,"\").Insert(11,$SourceVMXShort)) -eq $true){
                Write-Warning "Destination File exists..."
                $DestinationExists = $true
            }
            $Destination = ("DestMount:").insert(10,"\")
            ; break
        }

    }

正如你所看到的,如果我可以更新$ DestinationType以便我可以重新使用其他开关块中的语句,而不是额外的'ifs'

,那将会更优雅。

2 个答案:

答案 0 :(得分:0)

虽然我认为您不能更改switch语句变量mid check,但您可以执行嵌套的switch语句。此代码提供您请求的输出:

$var = "a"
switch ($var){
    "a" {Write-Host "1st match for 'a'"}
    "b" {Write-Host "1st match for 'b'"}
    "a" {Write-Host "2nd match for 'a'"
            $var = "b" 
            switch ($var) {
                "b" {Write-Host "2st match for 'b'"}
            } #End sub-switch
        } #End "A" check
} #End Primary switch

现在,我不确定你的总体目标是什么,可能有更好的方法来实现功能等。

更新问题和评论后编辑:

通过查看更新的代码,您可以提取设置$DestinationExists = $true的if语句。您可以重新组织if语句,以便它们只显示一次。不幸的是,没有办法让switch语句改变变量mid-switch。从您的评论中,您可以添加一个额外的参数来指定类型,因此您可以根据类型使用一个大的switch语句。像这样:

switch ($DataType) {
    "String" {<#Things to do if string#>}
    "OtherTypes" {<#Continue like this#>}
}#End Switch ($DataType)

我想在那时,我会开始使用参数集。这是一篇描述Parameter Sets

的博客

答案 1 :(得分:0)

这是一种有点复杂的方法。请注意,示例代码与OP中的代码类似但不相同。

add-type @"

using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Management.Automation;

public class PSVarEnumeration : IEnumerable
{
    private ScriptBlock _getterScript;

    public PSVarEnumeration(ScriptBlock getterScript)
    {
        _getterScript = getterScript;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
       return (IEnumerator) GetEnumerator();
    }

    public PSVarEnumerator GetEnumerator()
    {
        return new PSVarEnumerator(_getterScript);
    }
}

public class PSVarEnumerator : IEnumerator
{
    private ScriptBlock _getterScript;
    bool areDone = false;

    // position isn't used for anything
    int position = -1;

    public PSVarEnumerator(ScriptBlock getterScript)
    {
        _getterScript = getterScript;
    }

    public bool MoveNext()
    {
        if (!areDone) {
          if (Current != null) {
            position++;
            return true;
          } else {
            areDone = true;
            return false;
          }
        } else {
          return false;
        }
    }

    public void Reset()
    {
        position = -1;
        areDone = false;
    }

    object IEnumerator.Current
    {
        get
        {
            return Current;
        }
    }

    public Object Current
    {
        get
        {
            Collection<PSObject> results = _getterScript.Invoke();
            return results[0];
        }
    }
}

"@

$mySwitcher ="a"
$mySwitcherScript = {$mySwitcher}
$var = new PSVarEnumeration ( $mySwitcherScript)

switch ($var){

    "a" {Write-Host "1st match for 'a'"}
    "b" {Write-Host "1st match for 'b'"}
    "a" {Write-Host "2nd match for 'a'"; $mySwitcher = "b" ; continue}
    "b" {Write-Host "2nd match for 'b'"; $mySwitcher = $null}
}

<#
Output I get is:

1st match for 'a'
2nd match for 'a'
1st match for 'b'
2nd match for 'b'

#>