给定一个正确定义的变量
$test = New-Object System.Collections.ArrayList
.Add
用数组中的项目计数污染管道,而 .AddRange
才不是。$test.Add('Single')
将计数转储到控制台。 $test.AddRange(@('Single2'))
无需额外努力即可清洁。为什么会有不同的行为?这只是一个疏忽,还是有一些我不理解的故意行为?鉴于
.AddRange
不使用变量时需要强制转换为数组(即已经是数组)我倾向于使用 [void]$variable.Add('String')
当我知道我只需要添加一项时,[void]$test.AddRange($variable)
当我将数组添加到数组时,即使 $variable
仅包含或只能包含单个项目。 [void]
这不是必需的,但我想知道拥有它是否只是最佳实践,当然取决于上面的答案。还是我在那里也错过了一些东西?
最佳答案
Why the different behavior? Is it just an oversight, or is there some intentional behavior I am not understanding?
因为很多年前,有人决定是这样
ArrayList
应该表现!Add()
返回参数插入列表的索引,这可能确实有用且有意义。与
AddRange()
另一方面,目前还不清楚为什么它应该返回任何东西,如果是,是什么?输入参数中第一项的索引?最后?还是应该返回一个包含所有插入索引的可变大小数组?那会很尴尬!所以谁实现了ArrayList
决定不归还任何东西。在
C#
或 VB.NET
,其中 ArrayList
最初设计时,“污染管道”实际上并不作为一个概念存在,如果有人调用 .Add()
,运行时将简单地省略将返回值复制回调用者的操作。不分配给变量。The
[void]
here isn't required, but I wonder if it's just best practice to have it, depending of course on the answer above. Or am I missing something there too?
不,完全没有必要。
AddRange()
不会神奇地有一天会改变以输出任何东西。如果您不需要知道插入索引,请使用
[System.Collections.Generic.List[psobject]]
反而:$list = [System.Collections.Generic.List[psobject]]::new()
# this won't return anything, no need for `[void]`
$list.Add(123)
如果由于某种原因您必须使用
ArrayList
,您可以通过覆盖 Add()
来“静音”它方法:function New-SilentArrayList {
# Create a new ArrayList
$newList = [System.Collections.ArrayList]::new()
# Create a new `Add()` method, then return the list
$newAdd = @{
InputObject = $newList
MemberType = 'ScriptMethod'
Name = 'Add'
Value = {param($obj) $this.AddRange(@($obj))}
}
Write-Output $(
Add-Member @newAdd -Force -PassThru
) -NoEnumerate
}
现在您的
ArrayList
的 Add()
永远不会再偷窥了!PS C:\> $list = New-SilentArrayList
PS C:\> $list.Add(123)
PS C:\> $list
123
关于powershell - ArrayList .Add 与 .AddRange 对比管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61555660/