1010namespace Microsoft . AspNetCore . Internal . Dictionary
1111{
1212 /// <summary>
13- /// An <see cref="IDictionary{String, Object}"/> type for route values .
13+ /// An <see cref="IDictionary{String, Object}"/> type to hold a small amount of items (4 or less in the common case) .
1414 /// </summary>
1515 internal class SmallCapacityDictionary < TKey , TValue > : IDictionary < TKey , TValue > , IReadOnlyDictionary < TKey , TValue > where TKey : notnull
1616 {
@@ -27,6 +27,7 @@ internal class SmallCapacityDictionary<TKey, TValue> : IDictionary<TKey, TValue>
2727 /// The new instance will take ownership of the array, and may mutate it.
2828 /// </summary>
2929 /// <param name="items">The items array.</param>
30+ /// <param name="comparer"></param>
3031 /// <returns>A new <see cref="SmallCapacityDictionary{TKey, TValue}"/>.</returns>
3132 public static SmallCapacityDictionary < TKey , TValue > FromArray ( KeyValuePair < TKey , TValue > [ ] items , IEqualityComparer < TKey > ? comparer = null )
3233 {
@@ -39,11 +40,14 @@ public static SmallCapacityDictionary<TKey, TValue> FromArray(KeyValuePair<TKey,
3940
4041 if ( items . Length > DefaultArrayThreshold )
4142 {
42- // Don't use dictionary for large arrays.
43- var dict = new Dictionary < TKey , TValue > ( comparer ) ;
43+ // Use dictionary for large arrays.
44+ var dict = new Dictionary < TKey , TValue > ( items . Length , comparer ) ;
4445 foreach ( var item in items )
4546 {
46- dict [ item . Key ] = item . Value ;
47+ if ( item . Key != null )
48+ {
49+ dict [ item . Key ] = item . Value ;
50+ }
4751 }
4852
4953 return new SmallCapacityDictionary < TKey , TValue > ( comparer )
@@ -153,23 +157,16 @@ public SmallCapacityDictionary(IEqualityComparer<TKey> comparer, int capacity)
153157 /// property names are keys, and property values are the values, and copied into the dictionary.
154158 /// Only public instance non-index properties are considered.
155159 /// </remarks>
156- public SmallCapacityDictionary ( IEnumerable < KeyValuePair < TKey , TValue > > values )
160+ public SmallCapacityDictionary ( IEnumerable < KeyValuePair < TKey , TValue > > values , IEqualityComparer < TKey > comparer = null , int capacity = 0 )
157161 {
158- _comparer = EqualityComparer < TKey > . Default ;
162+ _comparer = comparer ?? EqualityComparer < TKey > . Default ;
159163
160- if ( values is IEnumerable < KeyValuePair < TKey , TValue > > keyValueEnumerable )
161- {
162- _arrayStorage = Array . Empty < KeyValuePair < TKey , TValue > > ( ) ;
164+ _arrayStorage = new KeyValuePair < TKey , TValue > [ capacity ] ;
163165
164- foreach ( var kvp in keyValueEnumerable )
165- {
166- Add ( kvp . Key , kvp . Value ) ;
167- }
168-
169- return ;
166+ foreach ( var kvp in values )
167+ {
168+ Add ( kvp . Key , kvp . Value ) ;
170169 }
171-
172- _arrayStorage = Array . Empty < KeyValuePair < TKey , TValue > > ( ) ;
173170 }
174171
175172 /// <inheritdoc />
@@ -184,11 +181,6 @@ public TValue this[TKey key]
184181
185182 TryGetValue ( key , out var value ) ;
186183
187- if ( value == null )
188- {
189- ThrowKeyNotFoundException ( nameof ( key ) ) ;
190- }
191-
192184 return value ;
193185 }
194186
@@ -604,12 +596,6 @@ private static void ThrowArgumentNullExceptionForKey()
604596 throw new ArgumentNullException ( "key" ) ;
605597 }
606598
607- [ DoesNotReturn ]
608- private static void ThrowKeyNotFoundException ( string keyName )
609- {
610- throw new KeyNotFoundException ( $ "The given key '{ keyName } ' was not present in the dictionary.") ;
611- }
612-
613599 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
614600 private void EnsureCapacity ( int capacity )
615601 {
0 commit comments