运行以下代码,我认为无法编辑$CONST_HASH
。
Set-Variable -Name CONST_HASH -Value @{a=1} -Option Constant
如果我尝试重置变量,则失败
$CONST_HASH2 = @{}
但我可以附加或修改其值。
$CONST_HASH.A = 10
$CONST_HASH.B = 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中找到解释此行为的任何内容。