@@ -55,7 +55,22 @@ public int Count
5555 {
5656 get
5757 {
58- return Keys . Count ;
58+ var count = _localValues . Count ;
59+
60+ if ( _parent . Count == 0 )
61+ {
62+ return count ;
63+ }
64+
65+ foreach ( var key in _parent . Keys )
66+ {
67+ if ( ! _localValues . ContainsKey ( key ) )
68+ {
69+ count ++ ;
70+ }
71+ }
72+
73+ return count ;
5974 }
6075 }
6176
@@ -84,7 +99,7 @@ public bool IsReadOnly
8499 /// but it is guaranteed to be the same order as the corresponding values in the <see cref="ICollection{TKey}"/>
85100 /// returned by the <see cref="Values"/> property.
86101 /// </remarks>
87- public ICollection < TKey > Keys => GetOrderedKeysSnapshot ( ) ;
102+ public ICollection < TKey > Keys => GetMergedKeysSnapshot ( ) ;
88103
89104 /// <summary>
90105 /// Gets an <see cref="ICollection{TKey}"/> containing the values of the dictionary.
@@ -101,7 +116,7 @@ public ICollection<TValue> Values
101116 {
102117 get
103118 {
104- var keys = GetOrderedKeysSnapshot ( ) ;
119+ var keys = GetMergedKeysSnapshot ( ) ;
105120 var values = new TValue [ keys . Count ] ;
106121 for ( var i = 0 ; i < keys . Count ; i ++ )
107122 {
@@ -222,7 +237,7 @@ public bool Contains(KeyValuePair<TKey, TValue> item)
222237 [ SuppressMessage ( "CA1841" , "CA1841" , Justification = "False positive. This isn't a standard set of keys like other dictionaries." ) ]
223238 public bool ContainsKey ( TKey key )
224239 {
225- return Keys . Contains ( key ) ;
240+ return _localValues . ContainsKey ( key ) || _parent . ContainsKey ( key ) ;
226241 }
227242
228243 /// <summary>
@@ -237,8 +252,26 @@ public bool ContainsKey(TKey key)
237252 /// </param>
238253 public void CopyTo ( KeyValuePair < TKey , TValue > [ ] array , int arrayIndex )
239254 {
240- var resolved = ( ICollection < KeyValuePair < TKey , TValue > > ) new Dictionary < TKey , TValue > ( this ) ;
241- resolved . CopyTo ( array , arrayIndex ) ;
255+ if ( array == null )
256+ {
257+ throw new ArgumentNullException ( nameof ( array ) ) ;
258+ }
259+
260+ if ( arrayIndex < 0 || arrayIndex > array . Length )
261+ {
262+ throw new ArgumentOutOfRangeException ( nameof ( arrayIndex ) ) ;
263+ }
264+
265+ if ( array . Length - arrayIndex < Count )
266+ {
267+ throw new ArgumentException ( FallbackDictionaryResources . InsufficientArraySpace , nameof ( array ) ) ;
268+ }
269+
270+ var index = arrayIndex ;
271+ foreach ( var kvp in EnumerateKeyValuePairs ( ) )
272+ {
273+ array [ index ++ ] = kvp ;
274+ }
242275 }
243276
244277 /// <summary>
@@ -249,10 +282,7 @@ public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
249282 /// </returns>
250283 public IEnumerator < KeyValuePair < TKey , TValue > > GetEnumerator ( )
251284 {
252- foreach ( var key in GetOrderedKeysSnapshot ( ) )
253- {
254- yield return new KeyValuePair < TKey , TValue > ( key , this [ key ] ) ;
255- }
285+ return EnumerateKeyValuePairs ( ) . GetEnumerator ( ) ;
256286 }
257287
258288 /// <summary>
@@ -326,7 +356,7 @@ IEnumerator IEnumerable.GetEnumerator()
326356 /// Gets the list of correctly ordered unique keys from the local and parent dictionaries.
327357 /// </summary>
328358 /// <returns>A new list containing the ordered unique set of keys.</returns>
329- private List < TKey > GetOrderedKeysSnapshot ( )
359+ private List < TKey > GetMergedKeysSnapshot ( )
330360 {
331361 var keys = new List < TKey > ( _localValues . Count + _parent . Count ) ;
332362 keys . AddRange ( _localValues . Keys ) ;
@@ -339,7 +369,24 @@ private List<TKey> GetOrderedKeysSnapshot()
339369 }
340370 }
341371
342- keys . Sort ( ) ;
343372 return keys ;
344373 }
374+
375+ private IEnumerable < KeyValuePair < TKey , TValue > > EnumerateKeyValuePairs ( )
376+ {
377+ foreach ( var kvp in _localValues )
378+ {
379+ yield return kvp ;
380+ }
381+
382+ foreach ( var parentKvp in _parent )
383+ {
384+ if ( _localValues . ContainsKey ( parentKvp . Key ) )
385+ {
386+ continue ;
387+ }
388+
389+ yield return parentKvp ;
390+ }
391+ }
345392}
0 commit comments