@@ -377,7 +377,7 @@ public TValue this[TKey key]
377
377
{
378
378
ThrowIfNull ( key ) ;
379
379
380
- bool modified = TryInsert ( index : - 1 , key , value , InsertionBehavior . OverwriteExisting ) ;
380
+ bool modified = TryInsert ( index : - 1 , key , value , InsertionBehavior . OverwriteExisting , out _ ) ;
381
381
Debug . Assert ( modified ) ;
382
382
}
383
383
}
@@ -392,8 +392,9 @@ public TValue this[TKey key]
392
392
/// - OverwriteExisting: If the key already exists, overwrites its value with the specified value, e.g. this[key] = value
393
393
/// - ThrowOnExisting: If the key already exists, throws an exception, e.g. Add(key, value)
394
394
/// </param>
395
+ /// <param name="keyIndex">The index of the added or existing key. This is always a valid index into the dictionary.</param>
395
396
/// <returns>true if the collection was updated; otherwise, false.</returns>
396
- private bool TryInsert ( int index , TKey key , TValue value , InsertionBehavior behavior )
397
+ private bool TryInsert ( int index , TKey key , TValue value , InsertionBehavior behavior , out int keyIndex )
397
398
{
398
399
// Search for the key in the dictionary.
399
400
uint hashCode = 0 , collisionCount = 0 ;
@@ -402,6 +403,9 @@ private bool TryInsert(int index, TKey key, TValue value, InsertionBehavior beha
402
403
// Handle the case where the key already exists, based on the requested behavior.
403
404
if ( i >= 0 )
404
405
{
406
+ keyIndex = i ;
407
+ Debug . Assert ( 0 <= keyIndex && keyIndex < _count ) ;
408
+
405
409
Debug . Assert ( _entries is not null ) ;
406
410
407
411
switch ( behavior )
@@ -467,6 +471,9 @@ private bool TryInsert(int index, TKey key, TValue value, InsertionBehavior beha
467
471
468
472
RehashIfNecessary ( collisionCount , entries ) ;
469
473
474
+ keyIndex = index ;
475
+ Debug . Assert ( 0 <= keyIndex && keyIndex < _count ) ;
476
+
470
477
return true ;
471
478
}
472
479
@@ -479,19 +486,27 @@ public void Add(TKey key, TValue value)
479
486
{
480
487
ThrowIfNull ( key ) ;
481
488
482
- TryInsert ( index : - 1 , key , value , InsertionBehavior . ThrowOnExisting ) ;
489
+ TryInsert ( index : - 1 , key , value , InsertionBehavior . ThrowOnExisting , out _ ) ;
483
490
}
484
491
485
492
/// <summary>Adds the specified key and value to the dictionary if the key doesn't already exist.</summary>
486
493
/// <param name="key">The key of the element to add.</param>
487
494
/// <param name="value">The value of the element to add. The value can be null for reference types.</param>
488
495
/// <exception cref="ArgumentNullException">key is null.</exception>
489
496
/// <returns>true if the key didn't exist and the key and value were added to the dictionary; otherwise, false.</returns>
490
- public bool TryAdd ( TKey key , TValue value )
497
+ public bool TryAdd ( TKey key , TValue value ) => TryAdd ( key , value , out _ ) ;
498
+
499
+ /// <summary>Adds the specified key and value to the dictionary if the key doesn't already exist.</summary>
500
+ /// <param name="key">The key of the element to add.</param>
501
+ /// <param name="value">The value of the element to add. The value can be null for reference types.</param>
502
+ /// <param name="index">The index of the added or existing <paramref name="key"/>. This is always a valid index into the dictionary.</param>
503
+ /// <exception cref="ArgumentNullException">key is null.</exception>
504
+ /// <returns>true if the key didn't exist and the key and value were added to the dictionary; otherwise, false.</returns>
505
+ public bool TryAdd ( TKey key , TValue value , out int index )
491
506
{
492
507
ThrowIfNull ( key ) ;
493
508
494
- return TryInsert ( index : - 1 , key , value , InsertionBehavior . IgnoreInsertion ) ;
509
+ return TryInsert ( index : - 1 , key , value , InsertionBehavior . IgnoreInsertion , out index ) ;
495
510
}
496
511
497
512
/// <summary>Adds each element of the enumerable to the dictionary.</summary>
@@ -714,7 +729,7 @@ public void Insert(int index, TKey key, TValue value)
714
729
715
730
ThrowIfNull ( key ) ;
716
731
717
- TryInsert ( index , key , value , InsertionBehavior . ThrowOnExisting ) ;
732
+ TryInsert ( index , key , value , InsertionBehavior . ThrowOnExisting , out _ ) ;
718
733
}
719
734
720
735
/// <summary>Removes the value with the specified key from the <see cref="OrderedDictionary{TKey, TValue}"/>.</summary>
@@ -896,12 +911,22 @@ public void TrimExcess(int capacity)
896
911
/// otherwise, the default value for the type of the value parameter.
897
912
/// </param>
898
913
/// <returns>true if the <see cref="OrderedDictionary{TKey, TValue}"/> contains an element with the specified key; otherwise, false.</returns>
899
- public bool TryGetValue ( TKey key , [ MaybeNullWhen ( false ) ] out TValue value )
914
+ public bool TryGetValue ( TKey key , [ MaybeNullWhen ( false ) ] out TValue value ) => TryGetValue ( key , out value , out _ ) ;
915
+
916
+ /// <summary>Gets the value associated with the specified key.</summary>
917
+ /// <param name="key">The key of the value to get.</param>
918
+ /// <param name="value">
919
+ /// When this method returns, contains the value associated with the specified key, if the key is found;
920
+ /// otherwise, the default value for the type of the value parameter.
921
+ /// </param>
922
+ /// <param name="index">The index of <paramref name="key"/> if found; otherwise, -1.</param>
923
+ /// <returns>true if the <see cref="OrderedDictionary{TKey, TValue}"/> contains an element with the specified key; otherwise, false.</returns>
924
+ public bool TryGetValue ( TKey key , [ MaybeNullWhen ( false ) ] out TValue value , out int index )
900
925
{
901
926
ThrowIfNull ( key ) ;
902
927
903
928
// Find the key.
904
- int index = IndexOf ( key ) ;
929
+ index = IndexOf ( key ) ;
905
930
if ( index >= 0 )
906
931
{
907
932
// It exists. Return its value.
0 commit comments