Можно ли сделать хэш только для чтения? - PullRequest
0 голосов
/ 25 апреля 2018

Запустив приведенный ниже код, я предполагаю, что $CONST_HASH не может быть отредактировано.

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

Если я попытаюсь сбросить переменную, произойдет сбой

$CONST_HASH2 = @{}

Но я могу добавитьили изменить его значения.

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

Есть ли способ предотвратить это?

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Технически так работают ссылочные типы в .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> обертку для него.

0 голосов
/ 25 апреля 2018

Кажется, что это недостаток работы с объектами вместо типов значений, таких как строка.

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

Оба фактора создают переменную, которая не будет записана в.

Если выпосмотрите на переменную, которую вы загружаете

$CONST_HASH | gm

Вы можете видеть, что это коллекция.

Я не могу найти ничего в документации , которая объясняет это поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...