奇怪的行为:输入参数(具有多个以 "D" 或 "L" 字符结尾的值)
Strange behavior: Input parameter (with multiple values that end with "D" or "L" characters)
我有以下 PowerShell 函数:
function Get-Devices {
[CmdletBinding()]
param(
[Parameter(Mandatory=$False, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True, ParameterSetName='Code')]
[String[]]$Codes
)
foreach ($Code in $Codes){write-output $Code}
}
当我这样调用时:
Get-Devices -Code 92D, 88L
它产生了以下输出:
92
88
注意,最后一个字符D和字符L被剥离了。如果我将这些值括在引号中,我就能让它工作。此外,以下所有内容都将按预期工作:
Get-Devices -Code D92, L88
Get-Devices -Code 92E, 88F
Get-Devices -Code 34G, 12Z
Get-Devices -Code "92D", "88L"
特别注意上面的第二行。只有 D
和 L
足以给我带来问题。
具体是什么导致 D 和 L 从每个值的末尾被剥离? 我真的不想强迫人们为所有值添加周围的引号来避免这个具体问题。强制 Powershell 不从每个值的末尾删除 D
或 L
,而不需要为这些值加上引号的最简单的方法是什么?
我已经尝试将输入参数类型更改为:[Array[]]$Codes
。这对行为没有任何影响。我还确认在上述循环处理时所有值都被视为字符串类型。任何避免这种行为的帮助将不胜感激!
唯一的好消息是这段代码和各自的奇怪行为很容易重现....
要了解这里发生的事情,请记住 Powershell 与 .Net 有着密切的关系。查看有关在 C# 中声明数字文字的文档以获取线索:
我们可以通过检查 PowerShell language specification*:
来获得更具体的信息
- §2.3.5.1.1 整数文字 包括:
l
、kb
、mb
、gb
、tb
, 和 pb
.
- §2.3.5.1.2 真实文字 添加了
d
.
您会在这里看到有几个后缀(包括 D
和 L
)来指示您正在使用的特定类型的号码。我敢打赌所有其他后缀都会给您带来同样的问题。如果我是对的,我也会回头仔细看看这个断言:
I also confirmed all values are treated as a string type when processed by the above loop.
从您的代码来看,这甚至看起来是真的。然而,代码之前的一些东西首先将这些值解释为数字,然后将其转换为字符串。不幸的是,在这种情况下,它很可能是 shell 本身,这意味着除了要求引号外,您真的无能为力:(
*通过this question.
找到
非常有趣。我不知道这一点,也找不到任何文档,但在参数上下文中(参见 Get-Help about_Parsing
),D
和 L
似乎被解释为指示数字是否被视为 [decimal]
或 [long]
.
参见:
PS C:\> $ExecutionContext.InvokeCommand.ExpandString(2.74D)
2.74
PS C:\> $ExecutionContext.InvokeCommand.ExpandString(2.74L)
3
在 Param
块本身中您无能为力 - D
和 L
由解析器解释,即。按下 enter 后的步骤,但 就在 参数传递给函数
之前
我有以下 PowerShell 函数:
function Get-Devices {
[CmdletBinding()]
param(
[Parameter(Mandatory=$False, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True, ParameterSetName='Code')]
[String[]]$Codes
)
foreach ($Code in $Codes){write-output $Code}
}
当我这样调用时:
Get-Devices -Code 92D, 88L
它产生了以下输出:
92 88
注意,最后一个字符D和字符L被剥离了。如果我将这些值括在引号中,我就能让它工作。此外,以下所有内容都将按预期工作:
Get-Devices -Code D92, L88
Get-Devices -Code 92E, 88F
Get-Devices -Code 34G, 12Z
Get-Devices -Code "92D", "88L"
特别注意上面的第二行。只有 D
和 L
足以给我带来问题。
具体是什么导致 D 和 L 从每个值的末尾被剥离? 我真的不想强迫人们为所有值添加周围的引号来避免这个具体问题。强制 Powershell 不从每个值的末尾删除 D
或 L
,而不需要为这些值加上引号的最简单的方法是什么?
我已经尝试将输入参数类型更改为:[Array[]]$Codes
。这对行为没有任何影响。我还确认在上述循环处理时所有值都被视为字符串类型。任何避免这种行为的帮助将不胜感激!
唯一的好消息是这段代码和各自的奇怪行为很容易重现....
要了解这里发生的事情,请记住 Powershell 与 .Net 有着密切的关系。查看有关在 C# 中声明数字文字的文档以获取线索:
我们可以通过检查 PowerShell language specification*:
来获得更具体的信息- §2.3.5.1.1 整数文字 包括:
l
、kb
、mb
、gb
、tb
, 和pb
. - §2.3.5.1.2 真实文字 添加了
d
.
您会在这里看到有几个后缀(包括 D
和 L
)来指示您正在使用的特定类型的号码。我敢打赌所有其他后缀都会给您带来同样的问题。如果我是对的,我也会回头仔细看看这个断言:
I also confirmed all values are treated as a string type when processed by the above loop.
从您的代码来看,这甚至看起来是真的。然而,代码之前的一些东西首先将这些值解释为数字,然后将其转换为字符串。不幸的是,在这种情况下,它很可能是 shell 本身,这意味着除了要求引号外,您真的无能为力:(
*通过this question.
找到非常有趣。我不知道这一点,也找不到任何文档,但在参数上下文中(参见 Get-Help about_Parsing
),D
和 L
似乎被解释为指示数字是否被视为 [decimal]
或 [long]
.
参见:
PS C:\> $ExecutionContext.InvokeCommand.ExpandString(2.74D)
2.74
PS C:\> $ExecutionContext.InvokeCommand.ExpandString(2.74L)
3
在 Param
块本身中您无能为力 - D
和 L
由解析器解释,即。按下 enter 后的步骤,但 就在 参数传递给函数