我需要从一个数组的元素创建一个ReadOnlyCollection,但似乎ReadOnlyCollection元素只能在该集合的声明中定义。除了在下面的示例中在集合的声明中列出数组的每个元素之外,还有其他方法吗?
[byte[]]$arr=10,20,30
[System.Collections.ObjectModel.ReadOnlyCollection[byte]]$readOnly=
$arr[0],$arr[1],$arr[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()
显式创建数组的副本。