Разница между [string] :: Format и -f и оператором Array vs split - PullRequest
0 голосов
/ 14 мая 2018

Я написал этот код, чтобы продемонстрировать разницу в методе форматирования строк:

Пример использования 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 не работает и переходит ко второй версии команды, которая работает.

В чем разница между [string]::Format и оператором -f в powershell?

Ошибка первой версии команды:

$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 работает. Для меня они оба выглядят довольно эквивалентно.

Разница между двумя типами данных:

Split

Получить тип
IsPublic IsSerial Name                                     BaseType                                                                                                                                               
-------- -------- ----                                     --------                                                                                                                                               
True     True     String[]                                 System.Array                                                                                                                                           
подсчитывать
2

Массив

Получить тип
IsPublic IsSerial Name                                     BaseType                                                                                                                                               
-------- -------- ----                                     --------                                                                                                                                               
True     True     Object[]                                 System.Array                                                                                                                                           
подсчитывать
2

1 Ответ

0 голосов
/ 14 мая 2018

Если вы посмотрите на перегрузки для [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[]], даже если это может быть?

Из-за этой перегрузки:

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[]], это работает при определении литерального массива или если ваш массив был назначен как выходнойipeline.

Например, вы все равно можете использовать [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[];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...