首页 > 解决方案 > [string]::Format 和 -f 以及 Array vs split 运算符之间的区别

问题描述

我编写了这段代码来展示格式化字符串的方法的不同:

使用拆分的示例

$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块失败并移动到有效的命令的第二个版本。

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

标签: powershell

解决方案


如果您查看以下内容的重载[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如您所见,当您使用运算符时,结果是 a [String[]],而不是[Object[]]

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

[Object[]]即使它可能是,为什么它不被强制转换为?

由于这种过载:

static string Format(string format, 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运营商呢?

让我们看一下它的源代码

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

object[] formatArgsArray = formatArgs as object[];

推荐阅读