Конструктор класса Powershell Collection - PullRequest
0 голосов
/ 12 октября 2018

Я работал над проектом сценариев, который включает в себя создание пользовательских классов PowerShell.В настоящее время я пытаюсь понять следующий синтаксис

$Temp = [myclass[]]::new(1)

Этот синтаксис, кажется, создает общий список некоторого вида, где я могу указать размер списка.Есть ли способ для меня изменить конструктор для этого?В идеале я хотел бы сделать что-то вроде следующего:

[string[]]$ClassData = @('test1','test2','test3')
[myclass[]]$Temp = [myclass[]]::new($ClassData)

И это вызвало бы конструктор для myclass для каждого из элементов в $ ClassData.К сожалению, в настоящее время это не так, и я обошел ситуацию, используя следующее:

[string[]]$ClassData = @('test1','test2','test3')
[myclass[]]$Temp = @($ClassData | [myclass[]]::new($_))

Любая помощь или объяснения относительно того, как сделать всю эту работу, будет принята с благодарностью

1 Ответ

0 голосов
/ 12 октября 2018

Примечание: я предполагаю, что ваш рабочий пример имел в виду использовать [myclass]::new($_), а не [myclass[]]::new($_), то есть вы создаете один [myclass] экземпляр в каждой итерации цикла: @($ClassData | % { [myclass]::new($_) })


Вместо попытки передать массив значений инициализации в статический метод ::new() (т. Е. В конструктор за кадром), приведение it :

[myclass[]]$Temp = $ClassData

Обратите внимание, что [myclass[]] является массивом экземпляров типа [myclass], и если [myclass]::new($_) работает с $_представляющий одну строку, то приведенное выше приведение должно завершиться успешно.

По сути, PowerShell будет делать за кулисами то, что явно делает ваше решение на основе циклов.


Что касается , чтовы пробовали :

[myclass[]]::new($ClassData) не работает, потому что [array] (System.Array) не имеет конструктора , который принимает существующий массив для инициализации новогомассив с;единственный конструктор - это тот, который принимает размер (длина, количество элементов) массива, который можно проверить следующим образом:

PS> [object[]]::new

OverloadDefinitions
-------------------
System.Object[] new(int )

Необязательное чтение: приведение из хеш-таблиц / пользовательских объектов:

Приведения очень гибкие, гораздо больше, чем, например, в C #.

Даже если входной тип не может быть напрямую преобразован в целевой объекттип и целевой тип не имеет конструктора с одним аргументом для входного типа, PowerShell все еще может создавать экземпляры целевого типа, если удовлетворено все из следующих условий:

  • Целевой тип имеет открытый конструктор, без параметров . [1]
  • Тип ввода имеет тот же набор свойств, что и цельвведите или подмножество из них.
  • Все перекрывающиеся свойства сами совместимы по типу (свойства относятся к одному типу или могут быть преобразованы из типа входного свойства в тип целевого свойства).

Вот пример инициализации массива пользовательского класса (с использованием определения PSv5 + class) из массива, содержащего хеш-таблицу и пользовательский объект ([pscustomobject]), каждый из которых предоставляет подмножество свойств целевого типа.

# Define a class.
# Not defining a constructor explicitly implicitly defines
# a public, parameter-less one.
class Foo {
  [string] $Bar
  [int]    $Baz
}

# Create an array of [Foo] instances via initialization by a
# hashtable and a custom object.
[Foo[]] $fooArr = @{ Bar = 'None' }, [pscustomobject] @{ Baz = 42 }

Вывод $fooAr впоследствии приводит к:

Bar  Baz
---  ---
None   0
      42

Тото есть два [Foo] экземпляра были успешно созданы из входных объектов.

Для получения дополнительной информации о приведениях и преобразованиях типов в PowerShell см. этот ответ .


[1] Одобренное будущее расширение для PowerShell Core позволит инициализировать из хеш-таблиц / пользовательских объектов даже с конструкторами, имеющими параметры, если существует соответствующая перегрузка конструкторадля входного набора записей хеш-таблиц / свойств пользовательских объектов.

...