Подумал об этом, отвечая этот вопрос.
Как можно избежать необходимости полностью определять каждый отдельный тип в пространстве имен?
Это действительно очень утомительно писать System.Security.Cryptography.X509Certificates.X509Store
вместо того X509Store
, или [System.Security.Cryptography.X509Certificates.StoreName]::My
вместо того [StoreName]::My
.
В C # у вас есть using
директивы ... а что насчет Powershell?
ИЗМЕНИТЬ 1 - Это работает для типов:
$ns = "System.Security.Cryptography.X509Certificates"
$store = New-Object "$ns.X509Store"(StoreName,StoreLocation)
New-Object принимает строковый литерал в качестве определения типа, поэтому его можно построить программно.
РЕДАКТИРОВАТЬ 2 - Это работает для членов перечисления, используемых в качестве параметров:
$store = New-Object "$ns.X509Store"("My","LocalMachine")
Где "Мой" [System.Security.Cryptography.X509Certificates.StoreName]::My
а "LocalMachine" - это [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine
.
Имена литералов автоматически преобразуются в члены перечисления, если они размещены там, где ожидается член перечисления.
Я знаю, это немного поздно, но PowerShell v5 добавляет массу интересных языковых вещей. Один из них - «использование пространства имен».
PS> using namespace System.Security.Cryptography.X509Certificates; [X509Store]
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False X509Store System.Object
Для перечислений вам не нужно указывать полное имя типа. Например:
Ты можешь сделать это:
New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext([System.DirectoryServices.ActiveDirectory.DirectoryContextType]::Domain)
или гораздо более простая версия:
New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Domain')
Вы можете использовать строки для идентификации перечислений, которые хотите использовать, без необходимости использовать полностью оформленное имя. PowerShell выполняет приведение типов, чтобы вы преобразовали строки в значения перечисления. Используя конкретный пример, который вы показали выше, это означает, что вы можете сделать это:
[System.Security.Cryptography.X509Certificates.OpenFlags]'ReadWrite'
И Powershell правильно его преобразует (поэтому передача ReadWrite в параметр, который принимает значение перечисления OpenFlags, будет работать нормально). Если вы хотите передать несколько значений, вы можете сделать это следующим образом:
[System.Security.Cryptography.X509Certificates.OpenFlags]@('ReadWrite','IncludeArchived')
Обратите внимание, что я добавляю к этим командам префикс имени типа, но если бы вы передавали их типизированному параметру, вы бы просто не указали его.
Это должно приблизить вас на один шаг к возможности писать сценарии, которые работают с определенным пространством имен, без необходимости украшать все имена.
$_m = [math]
$_m::sin((45*($_m::pi/180)))
И это, похоже, работает:
[Reflection.Assembly]::Load("System.Security, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a")
$stoopidnamespace = 'System.Security.Cryptography.X509Certificates.X509Store'
New-Object $stoopidnamespace($null)
Но это некрасиво, когда ты делаешь это:
$stoopidnamespace = 'System.Security.Cryptography.X509Certificates'
New-Object $stoopidnamespace'.X509Store'($null)