13

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

4 回答 4

26

虽然您可以深入研究 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 和 3rd 方类型作为类型参数时会出现错误。后者需要装配合格:

# 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 中,此问题已得到修复。

于 2012-08-15T20:53:00.770 回答
0

是的,似乎有可能,但就像 PS 中的几乎所有其他东西一样,这也太丑陋了。这是现实世界的例子:

$requestItemsType是一个Dictionary<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)
于 2012-08-15T20:00:57.393 回答
0

如果您要创建定义了自定义类型的字典,则上面的示例不必那么复杂:

$propertiesType = ("System.Collections.Generic.Dictionary"+'`'+"2") -as "Type"
$propertiesType = $propertiesType.MakeGenericType( @( ("System.string" -as "Type"), ("Namespace.CustomType" -as "Type")))
$properties = [Activator]::CreateInstance($propertiesType)
于 2013-07-25T20:44:08.890 回答
0

我知道这可能有点老了,但这种解决方法似乎在 PowerShell 2 中运行良好,并且几乎可以用作直接替代品。

$foo = [activator]::CreateInstance(([System.Collections.Generic.List[string]] -as 'Type'))
于 2018-07-17T12:46:26.327 回答