Powershell: Adding a key of 'keys' to a Hashtable breaks access to the .Keys property

Created on 21 Feb 2017  路  8Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

PS C:> $h = @{}
PS C:> $h.Add('foo', 42)
PS C:> $h.Add('bar', 42)
PS C:> $h.Keys
bar
foo
PS C:> $h.Add('keys', 42)
PS C:> $h.Keys
42
PS C:> $h

Name Value
---- -----
bar 42
foo 42
keys 42

Expected behavior

The Hashtable's .Keys property should always return the KeyCollection value from the underlying Hashtable. (Note: this same issue occurs with .Values, .Count, etc.)

Actual behavior

The convenience feature of accessing a Hashtable's entries with property syntax hides the real properties.
Other collection types are not effected, for example, substituting the following works:
$h = [System.Collections.Generic.Dictionary[string,int]]::new()

Environment data

Name Value
---- -----
PSRemotingProtocolVersion 2.3
PSVersion 6.0.0-alpha
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
SerializationVersion 1.1.0.1
PSEdition Core
BuildVersion 3.0.0.0
CLRVersion
GitCommitId v6.0.0-alpha.16
WSManStackVersion 3.0

Resolution-By Design WG-Engine

All 8 comments

This would be a breaking change. Workaround is

$h.psbase.keys

I suspected it might be too late to change this behavior. It sure did lead to a subtle bug in my case - as the hashtable was being populated with words from user supplied text. Perhaps a documentation update?

Thank you for the more general workaround - .PSBase is one of those tricks I know but forget about.

Agree on documentation, I just submitted this PR: https://github.com/PowerShell/PowerShell-Docs/pull/1065

The problem does apply to any of the聽native properties, so Values and Count are both an issue as well (and for completeness IsFixedSize, IsReadOnly, IsSynchronized, and SyncRoot but there's unlikely to be much PowerShell code actually trying to read any of those).

I updated the PR to make it more generic about any collision

Yes, I think that covers it聽perfectly. Thanks again.

@bcdev-com Thanks for reporting this!

The .psbase workaround is handy - thanks, @SteveL-MSFT.

For a related discussion with more background information, see #7758

Was this page helpful?
0 / 5 - 0 ratings