哈希可以只读取吗?

时间:2018-04-25 19:53:58

标签: powershell

运行以下代码,我认为无法编辑$CONST_HASH

Set-Variable -Name CONST_HASH -Value @{a=1} -Option Constant 

如果我尝试重置变量,则失败

$CONST_HASH2 = @{}

但我可以附加或修改其值。

$CONST_HASH.A = 10
$CONST_HASH.B = 2

有没有办法阻止这种情况?

2 个答案:

答案 0 :(得分:2)

从技术上讲,这就是引用类型在.NET中的工作方式。当你使变量只读意味着,你不能使变量引用不同的对象,但你仍然可以改变引用的对象,如果它不是不可变的。除非对象本身支持,否则没有简单的方法可以使任意对象成为只读。

通常涉及使用只读包装器包装对象。对于通用集合,您可以使用ReadOnlyCollection<T>ReadOnlyDictionary<TKey,TValue>类。

我不知道让Hashtable只读的简单方法,但您可以使用OrderedDictionary代替,它提供内置支持以使其成为只读:

$ReadOnlyDictionary = ([ordered]@{ a = 1 }).AsReadOnly()

注意:这不能传递,如果将可变对象放在只读集合中,它仍然是可变的。例如对于数组:

$Dictionary = ([ordered]@{ Array = 1, 2, 3 }).AsReadOnly()

您无法将新数组分配给字典:

$Dictionary['Array'] = 4, 5, 6 # Error

但你仍然可以修改存储在这里的数组:

$Dictionary['Array'][0] = 4
$Dictionary['Array'][1] = 5
$Dictionary['Array'][2] = 6

为了使数组也是只读的,你也需要包装它:

$Dictionary = ([ordered]@{ Array = [Array]::AsReadOnly((1, 2, 3)) }).AsReadOnly()

注意:由于.NET中的数组不具有只读的内置支持,[Array]::AsReadOnly不返回数组,而是返回ReadOnlyCollection<T>包装器。

答案 1 :(得分:1)

这似乎是使用对象而不是像string这样的值类型的缺点。

Set-Variable -Name CONST_HASH4  -Option ReadOnly -Value ([string]1)
Set-Variable -Name CONST_HASH5  -Option Constant -Value ([string]1)

实际上两者都创建了一个不会被写入的变量。

如果您按

查看正在加载的变量
$CONST_HASH | gm

你可以看到它是一个集合。

我无法在documentation中找到解释此行为的任何内容。