[String] $DBNms = @();
делает $DBNms
переменную с ограничением по типу , поскольку литерал типа [string]
расположен влево переменной $DBNms
, тип которой тогда заблокирован в в виде строки; то есть как a single string .
Вы хотели создать строку array , которая в PowerShell представлена как [string[]]
:
[string[]] $DBNames = @()
Преобразования типов PowerShell автоматизированы c (и очень гибкие), поэтому [String] $DBNms = @()
не сообщает об ошибке , он тихо преобразует пустой массив (@()
) в пустую строку (как того требует ограничение типа):
PS> [string] $DBNames = @(); '' -eq $DBNames
True
Гораздо более эффективный способ сбора значений из нескольких итераций в массиве заключается в использовании оператора foreach
в качестве выражения , в этом случае PowerShell автоматически собирает выходные данные для вас:
[string[]] $DBNms = foreach ($DBName in $objDBNms){
# Output this expression's value as-is.
# PowerShell will collect the individual iterations' values for you.
$DBName.Item(0).ToString().Trim() + "."
}
Вышесказанное не только более кратко, чем ваш первоначальный подход, но и, что более важно, более эффективно:
На самом деле вы не можете напрямую добавить (добавить к) массив, потому что это неизменяемая структура данных.
Что PowerShell должен делать всякий раз, когда вы используете +=
с массивом, это выделять новый массив за кулисами с оригинальными элементами скопированы и добавлены новые элементы; новый массив затем автоматически присваивается переменной.
Примечание: альтернатива и следующее лучшее решение для использования всего l oop в качестве выражение должно использовать и эффективно расширяемый тип списка , в частности [System.Collections.Generic.List[object]]
(System.Collections.Generic.List`1
):
# Create the list.
# The 'System.' namespace prefix is optional.
[Collections.Generic.List[string]] $DBNms = @()
foreach ($DBName in $objDBNms) {
# Add to the list, using its .Add() method.
# Note: Do NOT try to add with +=
$DBNms.Add($DBName.Item(0).ToString().Trim() + ".")
}
You ' Этот подход понадобится вам, если ваш l oop будет делать больше, чем вывод одного значения за одну итерацию, например, необходимо добавить к несколько коллекций.
Примечание. Раньше он был обычным для использования System.Collections.ArrayList
экземпляров вместо; однако:
Использование этого типа больше не рекомендуется (см. предупреждение в связанной справке topi c); вместо этого используйте [System.Collections.Generic.List[object]]
, что дополнительно позволяет строго набирать коллекцию (замените [object]
на интересующий тип, такой как [string]
в приведенном выше коде).
У него есть недостаток метода .Add()
, который имеет возвращаемое значение , которое необходимо явно отключить (например, $null = $lst.Add(...)
), чтобы он не мог случайно загрязнить ваш код. поток вывода (выдаст неожиданный дополнительный вывод).