簡體   English   中英

如何編寫將接受System.Type類型的參數的PowerShell CmdLet?

[英]How to write a PowerShell CmdLet that will accept a parameter of type System.Type?

我想將Type傳遞給自定義CmdLet,如下所示:

PS> "1" | My-CmdLet -Check [System.String]

我想用-Check參數作為類型參數-Is在我的cmdlet的操作:

Function My-CmdLet {
    param(
        ${Actual},

        [System.String]
        ${Check}           # <-- I want to pass a type here
    )

    if (-not ($Actual -Is [Type] $Check)) {
        # ... 
    }
}

調用時如下:

PS> My-CmdLet 1 -Check [System.String]

結果錯誤:

Cannot convert the "[System.String]" value of type "System.String" to type  "System.Type". At MycmdLet.ps1:19 char:9
 +     if (-not ($Actual -Is [Type] $ExpectedType)) {
 +         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
 + FullyQualifiedErrorId : InvalidCastFromStringToType

我嘗試使用[System.String][System.Type] [System.Object][System.RunTimeType]作為Check參數的類型,但是這些似乎都不起作用。

為了比較:

我可以像這樣將類型傳遞給Where-Object cmdlet:

PS> Get-Process | Where-Object StartTime -Is [System.Datetime]

(在這種情況下,值“ [System.DateTime]”傳遞給類型為[System.Object]的CmdLet參數$Value

我可以將Type與-Is運算符配合使用,如下所示:

PS> "1" -Is [System.String]
True

我如何申報-Check我的cmdlet的參數?

您有什么理由不首先聲明System.Type類型的參數嗎?

function Get-FullyQualifiedTypeName
{
    param([System.Type]$Type)

    Write-Host $Type.FullName
}

如果您傳遞實際的Type ,它將被接受,否則,解析器將嘗試為您將(部分)typename字符串解析為實際的[type] 無需重新實現解析器已經為您完成的功能!

PS> Get-FullyQualifiedTypeName $([psobject])
System.Management.Automation.PSObject
PS> Get-FullyQualifiedTypeName string
System.String

因此,就您而言,您會做類似

function Check-Type
{
    param(
        [Parameter(Mandatory,ValueFromPipeLine)]
        [psobject]$Actual,
        [Parameter(Mandatory)]
        [System.Type]$Check
    )

    $Actual -is $Check
}

應該會給您您想要的東西:

PS> "1" |Check-Type -Check string
True
PS> "1" |Check-Type -Check int
False
PS> 1 |Check-Type -Check int
True

[System.String] (請注意方括號)是一個表達式,因此,如果不包裝在分組表達式()或子表達式$()中,則不能將其用作參數值。 它只是用於[type]::GetType("System.String") (c#中的typeof() [type]::GetType("System.String")的PowerShell快捷方式。

System.String不過是PowerShell的自動類型轉換將成功轉換為字符串Type -object。

function Test-Type
{
    param(
        [Parameter(Mandatory=$true,ValueFromPipeLine=$true)]
        [PSObject]$Object,
        [Parameter(Mandatory=$true)]
        [System.Type]$Type
    )

    $Object -is $Type
}

Test-Type "c" -Type ([string])
1 | Test-Type -Type string
1 | Test-Type -Type ([int])
"1" | Test-Type -Type string

#Output
True
False
True
True

作為替代方案,您可以在函數內自己使用字符串參數並將其轉換為Type -object。 這樣,您可以自己刪除方括號以使類型轉換起作用。 像這樣:

function Test-Type
{
    param(
        [Parameter(Mandatory=$true,ValueFromPipeLine=$true)]
        [PSObject]$Object,
        [Parameter(Mandatory=$true)]
        [string]$Type
    )

    #Remove square brackets and convert to type-object
    $Type = [System.Type]($Type -replace '^\[(.*)\]$', '$1')

    $Object -is $Type
}

Test-Type "c" -Type [string]
1 | Test-Type -Type string
1 | Test-Type -Type [int]
"1" | Test-Type -Type string

#Output
True
False
True
True

將該參數聲明為字符串,然后通過[type]進行強制轉換。

例如:

$a=1
$b="System.Int32"
$a -is [type]$b

這應該返回$ true。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM