Я пытаюсь использовать описанный метод здесь, чтобы создать несколько пользовательских типов данных, и вместо того, чтобы иметь строку для каждого, я хотел бы определить хэш-таблицу имен и типов, таких как это
$pxAccelerators = @{
pxListObject = '[System.Collections.Generic.List[Object]]'
pxListString = '[System.Collections.Generic.List[String]]'
pxOrderedDictionary = '[System.Collections.Specialized.OrderedDictionary]'
}
Тогда я мог бы использовать что-то вроде этого
$typeAccelerators = [PowerShell].Assembly.GetType("System.Management.Automation.TypeAccelerators")
foreach ($key in $pxAccelerators.Keys) {
$name = $key
$type = $pxAccelerators.$key
$typeAccelerators::Add($key,$type)
}
чтобы перебрать хеш-таблицу и добавить каждый из них. Однако проблема, конечно, в том, что $type
не является фактическим типом, это строка. И $typeAccelerators::Add($key,$type)
нужна строка и фактический тип. Итак, в основном мне нужно привести строку типа '[System.Collections.Specialized.OrderedDictionary]'
к фактическому типу. Я нашел множество ссылок на приведение или принуждение одного типа данных к другому, но я не могу найти ссылки на то, как преобразовать строку в тип, определенный строкой. Я пробовал все эти удары в темноте
([System.Type]'[System.Collections.ArrayList]')::new()
[System.Type]'[System.Collections.ArrayList]'
[System.Type]'[System.Collections.ArrayList]' -as [System.Type]
'[System.Collections.ArrayList]' -as ([PowerShell].Assembly.GetType('[System.Collections.ArrayList]')
но безрезультатно. $type = ([PowerShell].Assembly.GetType('[System.Collections.ArrayList]'))
, похоже, работает, поскольку не генерирует исключения. Но $type.GetType()
бросает You cannot call a method on a null-valued expression.
. Интересно, что автодополнение с [PowerShell].Assembly.GetType('[System.Collections.ArrayList]').
показывает, что такие свойства, как BaseType
и FullName
, доступны, предполагая, что я действительно создал тип, но использование .GetType()
в результате вызывает исключение. Я попытался
$pxAccelerators = @{
pxListObject = 'System.Collections.Generic.List[Object]'
pxListString = 'System.Collections.Generic.List[String]'
pxOrderedDictionary = 'System.Collections.Specialized.OrderedDictionary'
}
$typeAccelerators = [PowerShell].Assembly.GetType("System.Management.Automation.TypeAccelerators")
foreach ($key in $pxAccelerators.Keys) {
$name = $key
$type = [PowerShell].Assembly.GetType($pxAccelerators.$key)
$typeAccelerators::Add($key,$type)
}
[PSObject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Get
и ускорители добавляются, но типа, который нужно ускорить, нет, что позволяет предположить, что строка GetType()
на самом деле не создает тип.
Наконец, я нашел этот который, кажется, приближается. Но я не могу понять, как получить доступ к методу, не начиная уже с какого-то типа, и [System.Type].GetType('System.Int32')
выбрасывает, так что это кажется тупиком.
Я пытаюсь сделать что-то невозможное? Или просто отсутствует правильный механизм?
[]
, это просто способ написания литералов типа в PowerShell.Type.GetType
выбрасывает, потому что это не метод экземпляра;[Type]::GetType('System.Int32')
работает нормально. Даже с этимList[String]
не будет работать, потому что это не то, как тип называется в .NET (это будетList`1
, а затем создано сString
); самый дешевый способ сделать это -Invoke-Expression '[System.Collections.Generic.List[String]]'
, предполагая, что вы можете быть уверены, что ваши строки никогда не будут получены из пользовательского ввода (посколькуiex
выполняет произвольный код). - person Jeroen Mostert   schedule 01.12.2020[System.Collections.Generic.List[Object]].ToString()
? Некоторые эксперименты показывают, что[Type]::GetType()
будет правильно анализировать результирующую строку обратно в тип, то есть[Type]::GetType([System.Collections.Generic.List[Object]].ToString()) -eq [System.Collections.Generic.List[Object]]
этоtrue
(но я проверяю это с PS 7.1, так что это может быть недавним нововведением - я не думаю, что раньше он обрабатывал дженерики правильно). - person Jeroen Mostert   schedule 01.12.2020