2014-01-08 5 views
6

Сегодня я заметил заинтересованное поведение PowerShell, и я сделал следующий код, чтобы показать его. При запуске:PowerShell возвращает массив элементов из функции

function test() 
{ 
    $a = @(1,2); 
    Write-Host $a.gettype() 
    return $a; 
} 

$b = test 
Write-Host $b.gettype(); 

То, что вы получили это:

System.Object[] 
System.Object[] 

Однако при изменении кода:

function test() 
{ 
    $a = @(1); 
    Write-Host $a.gettype() 
    return $a; 
} 

$b = test 
Write-Host $b.gettype(); 

Вы получили:

System.Object[] 
System.Int32 

Может кто-то дает более подробную информацию об этой «функции», ? Кажется, спецификация PowerShell не упомянула об этом.

Спасибо.


Кстати, я проверил код на PowerShell версии 2, 3 & 4.

ответ

5

Powershell автоматически "разворачивает" массивов в определенных ситуациях, в вашем случае назначение:

PS> (test).GetType() 
System.Object[] 

IsPublic IsSerial Name          BaseType 
-------- -------- ----          -------- 
True  True  Int32         System.ValueType 

PS> $b = test 
System.Object[] 
PS> $b.GetType() 

IsPublic IsSerial Name          BaseType 
-------- -------- ----          -------- 
True  True  Int32         System.ValueType 

вы может обойтись путем явного введения массива в присваивание:

$b = ,(test) 
+1

Есть ли способ обеспечить это в определении функции, а не в вызывающий? –

+0

@ Шкотт: Не то, чтобы я знал. Имейте в виду, что PowerShell является языком сценариев и построен вокруг потребления и создания списков значений - что-то, что делает трубопровод естественным образом. Единственные места, которые я нашел до сих пор, когда можно было обрабатывать массивы в виде массивов, были бы ценны те, в которых вы уходите от сильных сторон PowerShell и пытаетесь написать код стиля C# вместо конвейера (или передавать массивы массивов вместо массивов объектов , который следует по тому же пути). Поэтому в целом я бы сказал, что это даже не ошибка надзора или дизайна, которая делает это громоздкой. – Joey

+0

Согласовано, по большей части. Есть карманы Powershell, где тип важен. Мой сценарий: я пишу небольшой модуль Powershell для обертывания внутренней конечной точки WCF в командлетах, которые используют New-WebServiceProxy. Прокси-методы принимают ввод как пользовательский тип, сгенерированный с помощью прокси-клиента, и у меня есть вспомогательный метод для их создания. Это хлопотно, когда я ожидаю, что мой помощник вернет мне массив, и он даст мне один элемент или null. Теперь вызывающий код должен знать внутренний динамический тип для генерации собственного пустого массива. –

-1

Это говорит вам, что это объект, потому что это технически.

PS C:\Users\Administrator> $arr = @(1,2,3,4,5) 
PS C:\Users\Administrator> $arr.GetType() 

IsPublic IsSerial Name          BaseType 
-------- -------- ----          -------- 
True  True  Object[]         System.Array 

Обратите внимание, что BaseType является System.Array

Но при выводе его с помощью Write-Host, он просто говорит вам, что это System.Object[]

PS C:\Users\Administrator> Write-Host $arr.GetType() 
System.Object[] 

Как это.

Так что имеет логический смысл, что мы можем запустить следующую команду, основываясь на приведенной выше таблице, чтобы узнать BaseType:

PS C:\Users\Administrator> Write-Host $arr.GetType().BaseType 
System.Array 
+1

Он сообщает им, что это объект * array *; обратите внимание на '[]'. – Joey

Смежные вопросы