从 Powershell 调用带有数组参数的构造函数

Posted

技术标签:

【中文标题】从 Powershell 调用带有数组参数的构造函数【英文标题】:Calling Constructor with Array Argument from Powershell 【发布时间】:2012-02-26 03:40:37 【问题描述】:

我是 powershell 的初学者,对 C# 有一定的了解。最近我在写这个powershell脚本,想创建一个Hashset。所以我写了($azAz 是一个数组)

[System.Collections.Generic.HashSet[string]]$allset = New-Object System.Collections.Generic.HashSet[string]($azAZ)

然后按下运行。我收到了这条消息:

New-Object : Cannot find an overload for "HashSet`1" and the argument count: "52".
At filename.ps1:10 char:55
+ [System.Collections.Generic.HashSet[string]]$allset = New-Object System.Collecti ...
+                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [New-Object], MethodException
    + FullyQualifiedErrorId :         ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

然后,我在 powershell 中搜索了带有数组参数的构造函数,并将代码更改为:

[System.Collections.Generic.HashSet[string]]$allset = New-Object System.Collections.Generic.HashSet[string](,$azAZ)

不知何故,我现在收到了这条消息:

New-Object : Cannot find an overload for "HashSet`1" and the argument count: "1".
At C:\Users\youngvoid\Desktop\test5.ps1:10 char:55
+ [System.Collections.Generic.HashSet[string]]$allset = New-Object System.Collecti ...
+                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [New-Object], MethodException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

找不到 HashSet 和参数计数 1 的重载?你在跟我开玩笑吗?谢谢。

【问题讨论】:

为什么是逗号 (, $azAZ) ?? 我不知道,我是从谷歌搜索得到的。我什至没有通读这篇文章,但至少它让 powershell 将 $azAZ 视为 1 个参数。也许是因为逗号表示单独的参数? 因为逗号是数组创建操作符,所以它把$azAZ变成了一个只有$azAZ元素的数组——我认为@($azAZ)是一种更清晰的创建数组的方式——一个数组。 显然@($azAZ) 不起作用,“喷溅运算符'@'不能用于引用表达式中的变量”所以必须使用逗号 【参考方案1】:

这应该可行:

[System.Collections.Generic.HashSet[string]]$allset = $azAZ

更新:

要在构造函数中使用数组,数组必须是强类型的。这是一个例子:

[string[]]$a = 'one', 'two', 'three'
$b = 'one', 'two', 'three'

# This works
$hashA = New-Object System.Collections.Generic.HashSet[string] (,$a)
$hashA
# This also works
$hashB = New-Object System.Collections.Generic.HashSet[string] (,[string[]]$b)
$hashB
# This doesn't work
$hashB = New-Object System.Collections.Generic.HashSet[string] (,$b)
$hashB

【讨论】:

谢谢,它成功了。无论如何,我的代码有什么错误? 我认为初始化集合是在 c# 3 中添加的语法糖。编译器首先创建集合,然后在幕后添加元素。 PowerShell 只是没有这种语法。 但是 hashset 类包含构造函数 HashSet(IEnumerable) 带有 1 个参数,只需检查 msdn。 @testgo 啊,你是对的。我又测试了一些,发现如果数组是强类型的,可以在构造函数中使用。请参阅我更新的答案中的示例。 如果要指定比较器,可以这样做 "$hashA = New-Object System.Collections.Generic.HashSet[string] @($a, [System.StringComparer]::OrdinalIgnoreCase) "【参考方案2】:

试试这样:

C:\> $allset = New-Object System.Collections.Generic.HashSet[string]
C:\> $allset.add($azAZ)
True

【讨论】:

您的方法也可以,但我打算使用 hashset 构造函数。但是,您的方法既漂亮又优雅 等等,您的 $allset.add($azAZ) 将 $azAZ 中的所有元素添加为 1 个元素!这里肯定有问题。 是的,add() 就是这样做的。我误解了你的需求。从 arry 值填充 HasSet 的正确方法是在 Rynant 答案中。 @testgo 你也可以用$azAZ| foreach$allset.Add($_)单独添加元素 HashSet<T>.UnionWith(IEnumerable<T>): $allset.UnionWith( [string[]]$azAZ )(仅当数组是对象数组且不是强类型时才需要强制转换)。

以上是关于从 Powershell 调用带有数组参数的构造函数的主要内容,如果未能解决你的问题,请参考以下文章

PowerShell 中的构造函数链接 - 调用同一类中的其他构造函数

带有参数的 PowerShell 调用不替代 PARAM 来安装 MSI

如何从 TeamCity 构建配置中设置 PowerShell 开关参数

试图让高阶函数在powershell中工作

从 Java 调用带有数组输出参数的 Oracle 存储过程

对带有数组的构造函数的未定义引用[重复]