Description
Background and motivation
There is no way to set the value of an entry by index in the generic SortedList<TKey, TValue>
like there is in the non-generic version. This causes code to incur a BinarySearch cost (log n) to set the value when the index is already known.
I'm rather surprised nobody has mentioned this here even though there is interest over on StackOverflow (4 years old).
API Proposal
(Updated to reflect API Review's conclusions)
namespace System.Collections.Generic
{
public class SortedList<TKey, TValue>
{
+ public TKey GetKeyAtIndex(int index)
- private TKey GetKey(int index)
{ ... }
+ public TValue GetValueAtIndex(int index)
- private TValue GetByIndex(int index)
{ ... }
+ public void SetValueAtIndex(int index, TValue value)
+ {
+ if (index < 0 || index >= _size)
+ throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
+ values[index] = value;
+ version++;
+ }
Usage Examples
Allows an overriding class to handle complicated scenarios
Such as this example in which a binary search must be performed before deciding between a set or remove operation.
var index = this.IndexOfKey(key);
var newValue = this.Values[index] + incrValue;
if (newValue == 0) // or any condition that can only be decided once the index is known
this.RemoveAt(index);
else
this.SetValueByIndex(index, newValue);
Risks
The index of a particular key could change via another thread between acquisition and use. However, none of the other currently implemented methods in SortedList<TKey, TValue>
take precautions to make the class thread-safe.