Powershell中泛型类型的通用类型

时间:2012-08-15 18:39:50

标签: powershell

Powershel的仿制药非常令人困惑。 要实例化一个简单的列表,你需要用手鼓跳舞:

$type = ("System.Collections.Generic.List"+'`'+"1") -as "Type"
$type= $type.MakeGenericType("System.string" -as "Type")
$o = [Activator]::CreateInstance($type)

但是,如果我需要更复杂的东西,比如:<Dictionary<string,List<Foo>>,例如

或例如:Dictionary<string,List<string>>

$listType = ("System.Collections.Generic.List"+'`'+"1") -as "Type"
$listType = $listType.MakeGenericType("System.string" -as "Type")
$L = [Activator]::CreateInstance($listType)

$dicType = ("System.Collections.Generic.Dictionary"+'`'+"2") -as "Type"

#the next line is problematic
$dicType = $dicType.MakeGenericType( 
     @( ("system.string" -as "Type"), 
        ("System.Collections.Generic.List" as "Type)) # and that's of course wrong
      )

$D = [Activator]::CreateInstance($dicType )

4 个答案:

答案 0 :(得分:18)

虽然您可以深入研究CLR内部表示并为自己的生活带来困难,但您

$dict = new-object 'collections.generic.dictionary[string,int]'
$dict.add("answer", 42)

想要一个类型文字表示吗?

[collections.generic.dictonary[string,int]]

完成。泛型类型参数怎么样?

$dictOfList = new-object 'collections.generic.dictionary[string,
    [collections.generic.list[int]]]'

完成。

但是,有一个不幸的问题。在PowerShell 2.0中,将BCL和第三方类型混合并匹配为类型参数时会出现错误。后者需要装配合格:

# broken over two lines for clarity with backtick escape
$o = new-object ('collections.generic.dictionary[[{0}],[{1}]]' -f `
        [type1].fullname, [type2].fullname)

希望这会有所帮助。在PowerShell 3.0中,这已得到修复。

答案 1 :(得分:0)

是的,似乎有可能,但就像PS中的其他几乎一样,这也很难看。 这是现实世界的例子:

$requestItemsTypeDictionary<string, List<Amazon.DynamoDB.Model.WriteRequest>>

$wrt = ("System.Collections.Generic.List``1" -as "Type") 
$wrt = $wrt.MakeGenericType( @( ("Amazon.DynamoDB.Model.WriteRequest" -as "Type")))

$requestItemsType = ("System.Collections.Generic.Dictionary"+'`'+"2") -as "Type"
$requestItemsType = $requestItemsType.MakeGenericType( @( ("System.string" -as "Type"), ($wrt)))
$ri = [Activator]::CreateInstance($requestItemsType)
$ri.Add("TaskLog",$writeRequests)

答案 2 :(得分:0)

如果你要创建一个定义了自定义类型的字典,上面的例子就不必那么复杂了:

$propertiesType = ("System.Collections.Generic.Dictionary"+'`'+"2") -as "Type"
$propertiesType = $propertiesType.MakeGenericType( @( ("System.string" -as "Type"), ("Namespace.CustomType" -as "Type")))
$properties = [Activator]::CreateInstance($propertiesType)

答案 3 :(得分:0)

我知道这可能有点老,但是这种解决方法在PowerShell 2中似乎可以很好地工作,并且几乎可以用作直接替代方法。

$foo = [activator]::CreateInstance(([System.Collections.Generic.List[string]] -as 'Type'))