TheIncorrigible1 предоставил критический указатель в комментарии к вопросу:
метод PowerShell *1005* конструирование путем приведения из хеш-таблицы работает, только если целевой тип(также) имеет конструктор , который:
Сообщение об ошибке, которое вы видите, подразумевает, что [Microsoft.HyperV.PowerShell.HardDiskDrive]
не не имеет такой конструктор (см. Нижний раздел для ознакомления с проверкой конструкторов).
Предполагая, что тип с таким конструктором имеет public свойства, которые устанавливаются , вы можете приведение из хеш-таблицы, чьи записи соответствуют любое подмножество этих свойств , где ключ каждой записи должен быть именем такого свойства, а его значение - совместимым с типом (либо уже того же типа, что и свойство, либо может быть преобразовано в него).
PowerShell создает экземпляр типа с помощью конструктора без параметровсначала, а затем задает открытые свойства, указанные в хеш-таблице.
Вот (несколько надуманный) пример:
$obj = [System.Exception] @{ # just [Exception] works too, because 'System.' is implied
HResult = 0x8000400
Source = 'SomeModule'
}
Выше приведен эквивалент:
$obj = New-Object System.Exception; $obj.HResult = 0x8000400; $obj.Source = 'SomeModule'
Из-за необходимости использования конструктора без параметров метод хеш-таблицы в настоящее время в первую очередь полезен для DTO -подобных "пакетов свойств" .
Если все открытые конструкторы данного типа do имеют параметры , метод хэш-таблицы не будет работать, и вы должны вызвать конструктор для создания экземпляра типа - либо статическим методом ::new
(PSv5 +), либо с помощью New-Object
командлета ;например, чтобы вызвать перегрузку (int year, int month, int day)
конструктора [System.DateTime]
:
New-Object DateTime -ArgumentList 2018, 12, 1 # '-ArgumentList' is optional
[DateTime]::new(2018, 12, 1) # PSv5+ equivalent
Для вызова конструктора single -параметра, cast может быть использована альтернатива - см. следующий раздел.
Однако, ожидается улучшение для PowerShell Core Подсказка к TessellatingHeckler . , который позволит использовать технику хеш-таблицы даже с конструкторами, имеющими параметры, если набор записей хеш-таблицы соответствует параметрам данной перегрузки конструктора.
Как правило, кромеиз описанного выше случая хеш-таблицы приводит ([<target-type>] <operand>
), а также неявные преобразования работают в следующих сценариях в порядке рассмотрения:
Эта информация была получена из исходного кода PowerShell Core здесь .
(a) Если целевой тип обозначен TypeConverterAttribute
атрибут, определяющий пользовательский TypeConverter
или PSTypeConverter
класс, который поддерживает преобразование из типа операнда.
Кроме того, эти пользовательские классы преобразователя могут быть связаны с типами через ETS PowerShell (расширенная система типов), через Update-TypeData -TypeConverter
)
(b) Если целевой тип поддерживает статический метод ::Parse()
для построения экземпляра из строки :
[DateTime] '2018-12-01'
# The above matches `::Parse()` overload `static datetime Parse(string s)`
# However, given that there's also an overload that accepts a
# System.IFormatProvider argument, PowerShell uses that in order
# to use *culture-invariant* parsing.
# Thus, the above is the equivalent of:
[DateTime]::Parse('2018-12-01', [cultureinfo]::InvariantCulture)
Дополнительная информация об использовании PowerShell инвариантную культуру можно найти в этом ответе .
(c) Если целевой тип имеет открытый конструктор с единственным параметром, операнд является идентичным типуили -совместим с:
[Exception] 'Something failed'
# The above matches constructor `Exception(string message)` and is the
# equivalent of:
New-Object Exception -ArgumentList 'Something failed'
[Exception]::new('Something failed')
(d) Если целевой тип определяет неявный или явный оператор преобразования для типа операнда.
(e) Если тип операнда реализует интерфейс IConvertible
для создания эквивалентного экземпляра целевого типа (который ограничен типами среды выполнения CLR (встроенные типы)).
В PSv5 + , легко проверить конструкторы данного (загруженного) типа : вызвать статический метод ::new
без скобок, который перечисляет перегрузки метода (сигнатуры) всех общедоступных конструкторов;используя пример типа [System.Random]
:
PS> [Random]::new
OverloadDefinitions
-------------------
System.Random new()
System.Random new(int Seed)
Наличие a new()
перегрузки - без параметров - свидетельствует об открытом конструкторе без параметров .
Если вообще нет вывода, подразумевается, что типне имеет общедоступных конструкторов.