如何将数组元素复制到ReadOnlyCollection?

时间:2018-08-19 17:20:19

标签: powershell

我需要从一个数组的元素创建一个ReadOnlyCollection,但似乎ReadOnlyCollection元素只能在该集合的声明中定义。除了在下面的示例中在集合的声明中列出数组的每个元素之外,还有其他方法吗?

[byte[]]$arr=10,20,30
[System.Collections.ObjectModel.ReadOnlyCollection[byte]]$readOnly=
 $arr[0],$arr[1],$arr[2]

谢谢

2 个答案:

答案 0 :(得分:2)

将数组传递给构造函数:

$readOnly = New-Object 'System.Collections.ObjectModel.ReadOnlyCollection[byte]' -ArgumentList @(,$arr)

或(PowerShell 5.0及更高版本):

$readOnly = [System.Collections.ObjectModel.ReadOnlyCollection[byte]]::new($arr)

现在,您的问题标题特别指明了复制数组元素-当心您将无法修改$readOnly,但其内容仍将反映对其包装的数组的更改:

PS C:\> $arr[0] = 100
PS C:\> $arr[0]
100
PS C:\> $readOnly[0]
100

如果您需要一个完全独立的只读集合,请先将数组复制到另一个数组,然后用只读集合覆盖变量引用:

$readOnly = [byte[]]::new($arr.Count)
$arr.CopyTo($readOnly, 0)
$readOnly = [System.Collections.ObjectModel.ReadOnlyCollection[byte]]::new($readOnly)

现在您可以修改$arr而不会影响$readOnly

PS C:\> $arr[0] = 100
PS C:\> $arr[0]
100
PS C:\> $readOnly[0]
10

答案 1 :(得分:1)

Mathias R. Jessen's helpful answer包含了很好的替代方法和背景信息,但是对于您而言,您可以简单地分配数组到类型受限的$readOnly variabl e:

[byte[]] $arr=10,20,30 
[System.Collections.ObjectModel.ReadOnlyCollection[byte]] $readOnly = $arr

在PSv3 +中,您也可以使用[Array]::AsReadOnly()

[byte[]] $arr=10,20,30 
$readOnly = [Array]::AsReadOnly($arr) # shorter, but doesn't lock in the type of $readOnly

如前所述,System.Collections.ObjectModel.ReadOnlyCollection<T>包装其输入数组,因此以后对输入数组元素的更改将反映在只读集合中。

但是,是否包装实际的 input 数组取决于其特定类型,因为Powershell可能在幕后为您创建 new 数组-请参见{{3 }}。

如有疑问,请使用$arr.Clone()显式创建数组的副本。