繁体   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