powershell - [string]::Format 和 -f 之间的区别,以及数组与分割运算符

标签 powershell

我编写此代码是为了展示格式化字符串方法的差异:

使用拆分的示例

$arr = 'that,way'

$arr = $arr -split ","

$arr.GetType()
$arr.Count

try {
$rundmc = [string]::format("It's like {0} and that's the {1} it is",$arr)
}
catch {
    Write-Host "String::format failed"
    $rundmc = "It's like {0} and that's the {1} it is" -f $arr
}
Write-Host $rundmc

将输入数组定义为实际数组的示例

$arr2 = @('that','way')

$arr2.GetType()
$arr2.Count

try {
$rundmc = [string]::format("It's like {0} and that's the {1} it is",$arr2)
}
catch {
    Write-Host "String::format failed"
    $rundmc = "It's like {0} and that's the {1} it is" -f $arr2
}
Write-Host $rundmc

在前半部分,try block 失败并转移到有效命令的第二个版本。

powershell 中的[string]::Format-f 运算符有什么区别?

该命令的第一个版本失败:

$rundmc = [string]::format("It's like {0} and that's the {1} it is",$arr)
Exception calling "Format" with "2" argument(s): "Index (zero based) must be greater than or equal to zero and less than the size of the argument list."
At line:1 char:1
+ $rundmc = [string]::format("It's like {0} and that's the {1} it is",$ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException

但是-f有效。对我来说,它们看起来相当相似。

两种数据类型之间的差异:

拆分

获取类型
IsPublic IsSerial Name                                     BaseType                                                                                                                                               
-------- -------- ----                                     --------                                                                                                                                               
True     True     String[]                                 System.Array                                                                                                                                           
数数
2

数组

获取类型
IsPublic IsSerial Name                                     BaseType                                                                                                                                               
-------- -------- ----                                     --------                                                                                                                                               
True     True     Object[]                                 System.Array                                                                                                                                           
数数
2

最佳答案

如果您查看 [string]::Format 的重载:

OverloadDefinitions                                                                                                    
-------------------                                                                                                    
static string Format(string format, System.Object arg0)                                                                
static string Format(string format, System.Object arg0, System.Object arg1)                                            
static string Format(string format, System.Object arg0, System.Object arg1, System.Object arg2)                        
static string Format(string format, Params System.Object[] args)                                                       
static string Format(System.IFormatProvider provider, string format, System.Object arg0)                               
static string Format(System.IFormatProvider provider, string format, System.Object arg0, System.Object arg1)           
static string Format(System.IFormatProvider provider, string format, System.Object arg0, System.Object arg1,           
System.Object arg2)                                                                                                    
static string Format(System.IFormatProvider provider, string format, Params System.Object[] args)

您可以看到您尝试使用的就是这个:

static string Format(string format, Params System.Object[] args)

请注意,它期望其值是一个对象数组。

当您使用 -split 运算符时,如您所见,结果是 [String[]],而不是 [Object[] ]

$arr = 'that,way'
$arr = $arr -split ","
$arr.GetType()
$arr -is [Object[]] # false

为什么它没有被强制转换为 [Object[]],即使它可以这样做?

由于这种重载:

静态字符串格式(字符串格式,System.Object arg0)

$arr -isnot [Object[]] 但是 $arr -is [Object],因此此重载完全匹配。

不幸的是,由于您的格式字符串包含 2 个替换,并且您调用了仅提供 1 个替换的重载,因此您会收到此错误。

如果您执行了 [String]::Format('Just 1: {0}', $arr) 您的调用将会成功(但结果将是 Just 1: System.String[] 因为在参数上调用了 .ToString() 方法)。

由于 PowerShell 中的大多数数组最终都为 [Object[]],因此在定义文字数组或将数组指定为管道的输出时,它会起作用。

例如,如果您执行以下任一操作,您仍然可以使用 [String[]] 版本的 $arr:

[String]::Format('{0}~{1}', $($arr))
[String]::Format('{0}~{1}', ([Object[]]$arr))
[String]::Format('{0}~{1}', ($arr -as [Object[]]))
[String]::Format('{0}~{1}', ($arr|%{$_}))

-f 运算符怎么样?

Let's look at the source code for it .

它所做的第一件事就是尝试将其参数转换为 object[]:

object[] formatArgsArray = formatArgs as object[];

关于powershell - [string]::Format 和 -f 之间的区别,以及数组与分割运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50321268/

相关文章:

regex - 如何在可以包含该分隔符的一系列路径中替换该分隔符?

c# - 从 Windows 服务远程处理的 PowerShell

node.js - 从 Windows PowerShell 运行 node.js 脚本时,参数转义未正确解释

c# - 获取 PowerShell 脚本以在 Azure 上运行 SharePoint 命令

powershell - 检查是否已配置 nuget 源

powershell - 每当我在 VS 代码 1.18 中打开集成终端时,PowerShell 都会崩溃

powershell - PowerShell 中的整数除法

xml - 如何在Powershell中使用冒号读取xml属性

xml - Powershell System.Xml.XmlElement 但我使用 System.Xml.XmlDocument?

c# - 带有哈希表/字典参数的 Powershell C# Cmdlet