SortedList<TKey, TValue> added GetKeyAtIndex, GetValueAtIndex, and SetValueAtIndex...
authorrhaokiel <rhaokiel@live.com>
Mon, 15 Nov 2021 15:52:40 +0000 (09:52 -0600)
committerGitHub <noreply@github.com>
Mon, 15 Nov 2021 15:52:40 +0000 (15:52 +0000)
* SortedList<TKey, TValue> added GetKeyAtIndex, GetValueAtIndex, and SetValueAtIndex

* Update src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs

Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com>
src/libraries/System.Collections/ref/System.Collections.cs
src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs
src/libraries/System.Collections/tests/Generic/SortedList/SortedList.Generic.Tests.cs

index ceaadeb..028b163 100644 (file)
@@ -606,10 +606,13 @@ namespace System.Collections.Generic
         public bool ContainsKey(TKey key) { throw null; }
         public bool ContainsValue(TValue value) { throw null; }
         public System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<TKey, TValue>> GetEnumerator() { throw null; }
+        public TKey GetKeyAtIndex(int index) { throw null; }
+        public TValue GetValueAtIndex(int index) { throw null; }
         public int IndexOfKey(TKey key) { throw null; }
         public int IndexOfValue(TValue value) { throw null; }
         public bool Remove(TKey key) { throw null; }
         public void RemoveAt(int index) { }
+        public void SetValueAtIndex(int index, TValue value) { }
         void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.Add(System.Collections.Generic.KeyValuePair<TKey, TValue> keyValuePair) { }
         bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.Contains(System.Collections.Generic.KeyValuePair<TKey, TValue> keyValuePair) { throw null; }
         void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.CopyTo(System.Collections.Generic.KeyValuePair<TKey, TValue>[] array, int arrayIndex) { }
index a7168b5..1a96e7c 100644 (file)
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System.Diagnostics;
@@ -536,13 +536,22 @@ namespace System.Collections.Generic
         }
 
         // Returns the value of the entry at the given index.
-        private TValue GetByIndex(int index)
+        public TValue GetValueAtIndex(int index)
         {
             if (index < 0 || index >= _size)
                 throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
             return values[index];
         }
 
+        // Sets the value of the entry at the given 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++;
+        }
+
         public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
         {
             return new Enumerator(this, Enumerator.KeyValuePair);
@@ -564,7 +573,7 @@ namespace System.Collections.Generic
         }
 
         // Returns the key of the entry at the given index.
-        private TKey GetKey(int index)
+        public TKey GetKeyAtIndex(int index)
         {
             if (index < 0 || index >= _size)
                 throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
@@ -1082,7 +1091,7 @@ namespace System.Collections.Generic
             {
                 get
                 {
-                    return _dict.GetKey(index);
+                    return _dict.GetKeyAtIndex(index);
                 }
                 set
                 {
@@ -1201,7 +1210,7 @@ namespace System.Collections.Generic
             {
                 get
                 {
-                    return _dict.GetByIndex(index);
+                    return _dict.GetValueAtIndex(index);
                 }
                 set
                 {
index f31ede5..8e4790f 100644 (file)
@@ -259,6 +259,59 @@ namespace System.Collections.Tests
 
         #endregion
 
+        #region GetKeyAtIndex
+
+        [Theory]
+        [MemberData(nameof(ValidCollectionSizes))]
+        public void SortedList_Generic_GetKeyAtIndex_EveryIndex(int count)
+        {
+            SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
+            Assert.All(Enumerable.Range(0, count), index =>
+            {
+                Assert.Equal(index, dictionary.IndexOfKey(dictionary.GetKeyAtIndex(index)));
+            });
+        }
+
+        [Theory]
+        [MemberData(nameof(ValidCollectionSizes))]
+        public void SortedList_Generic_GetKeyAtIndex_OutOfRangeIndicies(int count)
+        {
+            SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
+            Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetKeyAtIndex(-1));
+            Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetKeyAtIndex(int.MinValue));
+            Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetKeyAtIndex(count));
+            Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetKeyAtIndex(count + 1));
+        }
+
+        #endregion
+
+        #region GetValueAtIndex
+
+        [Theory]
+        [MemberData(nameof(ValidCollectionSizes))]
+        public void SortedList_Generic_GetValueAtIndex_EveryIndex(int count)
+        {
+            // Assumes no duplicate elements contained in the dictionary returned by GenericIDictionaryFactory
+            SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
+            Assert.All(Enumerable.Range(0, count), index =>
+            {
+                Assert.Equal(index, dictionary.IndexOfValue(dictionary.GetValueAtIndex(index)));
+            });
+        }
+
+        [Theory]
+        [MemberData(nameof(ValidCollectionSizes))]
+        public void SortedList_Generic_GetValueAtIndex_OutOfRangeIndicies(int count)
+        {
+            SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
+            Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetValueAtIndex(-1));
+            Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetValueAtIndex(int.MinValue));
+            Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetValueAtIndex(count));
+            Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetValueAtIndex(count + 1));
+        }
+
+        #endregion
+
         #region IndexOfKey
 
         [Theory]
@@ -377,6 +430,73 @@ namespace System.Collections.Tests
 
         #endregion
 
+        #region SetValueAtIndex
+
+        [Theory]
+        [MemberData(nameof(ValidCollectionSizes))]
+        public void SortedList_Generic_SetValueAtIndex_OnReadOnlySortedList_ThrowsNotSupportedException(int count)
+        {
+            if (IsReadOnly)
+            {
+                SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
+                Assert.Throws<NotSupportedException>(() => dictionary.SetValueAtIndex(0, CreateTValue(34543)));
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ValidCollectionSizes))]
+        public void SortedList_Generic_SetValueAtIndex_NonDefaultValueContainedInCollection(int count)
+        {
+            if (!IsReadOnly)
+            {
+                int seed = count * 251;
+                SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
+                KeyValuePair<TKey, TValue> pair = CreateT(seed++);
+                if (!dictionary.ContainsKey(pair.Key))
+                {
+                    dictionary.Add(pair.Key, pair.Value);
+                    count++;
+                }
+                TValue newValue = CreateTValue(seed++);
+                dictionary.SetValueAtIndex(dictionary.IndexOfKey(pair.Key), newValue);
+                Assert.Equal(newValue, dictionary[pair.Key]);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ValidCollectionSizes))]
+        public void SortedList_Generic_SetValueAtIndex_EveryIndex(int count)
+        {
+            if (!IsReadOnly)
+            {
+                int seed = count * 193;
+                SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
+                TValue newValue = CreateTValue(seed++);
+                Assert.All(Enumerable.Range(0, count), index =>
+                {
+                    Assert.NotEqual(newValue, dictionary.GetValueAtIndex(index));
+                    dictionary.SetValueAtIndex(index, newValue);
+                    Assert.Equal(newValue, dictionary.GetValueAtIndex(index));
+                });
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ValidCollectionSizes))]
+        public void SortedList_Generic_SetValueAtIndex_OutOfRangeIndicies(int count)
+        {
+            if (!IsReadOnly)
+            {
+                SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
+                Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.SetValueAtIndex(-1, default));
+                Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.SetValueAtIndex(int.MinValue, default));
+                Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.SetValueAtIndex(count, default));
+                Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.SetValueAtIndex(count + 1, default));
+            }
+        }
+
+        #endregion
+
         #region RemoveAt
 
         private void RemoveAt(SortedList<TKey, TValue> dictionary, KeyValuePair<TKey, TValue> element)