防止胁迫

Prevent coercion

假设:

Function Invoke-Foo {
  Param(
    [string[]]$Ids
  )
  Foreach ($Id in $Ids) {    
    Write-Host $Id
  }
}

如果我这样做:

PS> Invoke-Foo -ids '0000','0001'
0000
0001

如果我这样做:

PS> Invoke-Foo -ids 0000,0001
0
1

在第二种情况下,除了使它们成为显式字符串(第一种情况)之外,是否有其他方法可以防止强制转换?

不,不幸的是没有。

来自 about_Parsing 帮助文件:

When processing a command, the Windows PowerShell parser operates
in expression mode or in argument mode: 

    - In expression mode, character string values must be contained in
      quotation marks. Numbers not enclosed in quotation marks are treated
      as numerical values (rather than as a series of characters). 

    - In argument mode, each value is treated as an expandable string 
      unless it begins with one of the following special characters: dollar
      sign ($), at sign (@), single quotation mark ('), double quotation
      mark ("), or an opening parenthesis (().

因此,解析器会在将任何内容传递给函数之前评估 0001。我们可以用ExpandString()方法测试把0001当成"Expandable String"的效果:

PS C:\> $ExecutionContext.InvokeCommand.ExpandString(0001)
1

至少,如果你确定你的id在[0, 9999]范围内,你可以这样格式化:

Function Invoke-Foo {
    Param([int[]]$Ids)
    Foreach ($Id in $Ids) {    
        Write-Host ([System.String]::Format("{0:D4}", $Id))
    }
}

可以找到有关使用前导零填充数字的更多信息 here

这里需要注意的重要事项:

  1. 填充将适用于数字。我将参数类型更改为 int[],这样如果您传递字符串,它们将被转换为数字,并且填充也适用于它们。

  2. 这种方法(就像现在一样)将您限制在我之前提到的 ID 范围内,并且它始终会给您四零填充的输出,即使您将其传递为“003”