Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs')
-rw-r--r--src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs551
1 files changed, 270 insertions, 281 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs
index 76fe546fb..623257d3c 100644
--- a/src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs
+++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs
@@ -2,11 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-using System.Collections;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
+using System.Threading;
namespace System.Collections.Generic
{
@@ -35,7 +34,7 @@ namespace System.Collections.Generic
[DebuggerDisplay("Count = {Count}")]
[Serializable]
#if !MONO
- [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
+ [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
#endif
public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue>, ISerializable, IDeserializationCallback
{
@@ -221,7 +220,7 @@ namespace System.Collections.Generic
int i = FindEntry(key);
if (i >= 0) return _entries[i].value;
ThrowHelper.ThrowKeyNotFoundException(key);
- return default(TValue);
+ return default;
}
set
{
@@ -237,9 +236,7 @@ namespace System.Collections.Generic
}
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> keyValuePair)
- {
- Add(keyValuePair.Key, keyValuePair.Value);
- }
+ => Add(keyValuePair.Key, keyValuePair.Value);
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> keyValuePair)
{
@@ -272,30 +269,43 @@ namespace System.Collections.Generic
_count = 0;
_freeList = -1;
_freeCount = 0;
- _version++;
Array.Clear(_entries, 0, count);
}
}
public bool ContainsKey(TKey key)
- {
- return FindEntry(key) >= 0;
- }
+ => FindEntry(key) >= 0;
public bool ContainsValue(TValue value)
{
+ Entry[] entries = _entries;
if (value == null)
{
for (int i = 0; i < _count; i++)
{
- if (_entries[i].hashCode >= 0 && _entries[i].value == null) return true;
+ if (entries[i].hashCode >= 0 && entries[i].value == null) return true;
}
}
else
{
- for (int i = 0; i < _count; i++)
+ if (default(TValue) != null)
+ {
+ // ValueType: Devirtualize with EqualityComparer<TValue>.Default intrinsic
+ for (int i = 0; i < _count; i++)
+ {
+ if (entries[i].hashCode >= 0 && EqualityComparer<TValue>.Default.Equals(entries[i].value, value)) return true;
+ }
+ }
+ else
{
- if (_entries[i].hashCode >= 0 && EqualityComparer<TValue>.Default.Equals(_entries[i].value, value)) return true;
+ // Object type: Shared Generic, EqualityComparer<TValue>.Default won't devirtualize
+ // https://github.com/dotnet/coreclr/issues/17273
+ // So cache in a local rather than get EqualityComparer per loop iteration
+ EqualityComparer<TValue> defaultComparer = EqualityComparer<TValue>.Default;
+ for (int i = 0; i < _count; i++)
+ {
+ if (entries[i].hashCode >= 0 && defaultComparer.Equals(entries[i].value, value)) return true;
+ }
}
}
return false;
@@ -308,7 +318,7 @@ namespace System.Collections.Generic
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (index < 0 || index > array.Length)
+ if ((uint)index > (uint)array.Length)
{
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
@@ -330,14 +340,10 @@ namespace System.Collections.Generic
}
public Enumerator GetEnumerator()
- {
- return new Enumerator(this, Enumerator.KeyValuePair);
- }
+ => new Enumerator(this, Enumerator.KeyValuePair);
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
- {
- return new Enumerator(this, Enumerator.KeyValuePair);
- }
+ => new Enumerator(this, Enumerator.KeyValuePair);
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
@@ -368,6 +374,7 @@ namespace System.Collections.Generic
int i = -1;
int[] buckets = _buckets;
Entry[] entries = _entries;
+ int collisionCount = 0;
if (buckets != null)
{
IEqualityComparer<TKey> comparer = _comparer;
@@ -376,17 +383,53 @@ namespace System.Collections.Generic
int hashCode = key.GetHashCode() & 0x7FFFFFFF;
// Value in _buckets is 1-based
i = buckets[hashCode % buckets.Length] - 1;
- do
+ if (default(TKey) != null)
{
- // Should be a while loop https://github.com/dotnet/coreclr/issues/15476
- // Test in if to drop range check for following array access
- if ((uint)i >= (uint)entries.Length || (entries[i].hashCode == hashCode && EqualityComparer<TKey>.Default.Equals(entries[i].key, key)))
+ // ValueType: Devirtualize with EqualityComparer<TValue>.Default intrinsic
+ do
{
- break;
- }
-
- i = entries[i].next;
- } while (true);
+ // Should be a while loop https://github.com/dotnet/coreclr/issues/15476
+ // Test in if to drop range check for following array access
+ if ((uint)i >= (uint)entries.Length || (entries[i].hashCode == hashCode && EqualityComparer<TKey>.Default.Equals(entries[i].key, key)))
+ {
+ break;
+ }
+
+ i = entries[i].next;
+ if (collisionCount >= entries.Length)
+ {
+ // The chain of entries forms a loop; which means a concurrent update has happened.
+ // Break out of the loop and throw, rather than looping forever.
+ ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
+ }
+ collisionCount++;
+ } while (true);
+ }
+ else
+ {
+ // Object type: Shared Generic, EqualityComparer<TValue>.Default won't devirtualize
+ // https://github.com/dotnet/coreclr/issues/17273
+ // So cache in a local rather than get EqualityComparer per loop iteration
+ EqualityComparer<TKey> defaultComparer = EqualityComparer<TKey>.Default;
+ do
+ {
+ // Should be a while loop https://github.com/dotnet/coreclr/issues/15476
+ // Test in if to drop range check for following array access
+ if ((uint)i >= (uint)entries.Length || (entries[i].hashCode == hashCode && defaultComparer.Equals(entries[i].key, key)))
+ {
+ break;
+ }
+
+ i = entries[i].next;
+ if (collisionCount >= entries.Length)
+ {
+ // The chain of entries forms a loop; which means a concurrent update has happened.
+ // Break out of the loop and throw, rather than looping forever.
+ ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
+ }
+ collisionCount++;
+ } while (true);
+ }
}
else
{
@@ -404,6 +447,13 @@ namespace System.Collections.Generic
}
i = entries[i].next;
+ if (collisionCount >= entries.Length)
+ {
+ // The chain of entries forms a loop; which means a concurrent update has happened.
+ // Break out of the loop and throw, rather than looping forever.
+ ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
+ }
+ collisionCount++;
} while (true);
}
}
@@ -446,35 +496,87 @@ namespace System.Collections.Generic
if (comparer == null)
{
- do
+ if (default(TKey) != null)
{
- // Should be a while loop https://github.com/dotnet/coreclr/issues/15476
- // Test uint in if rather than loop condition to drop range check for following array access
- if ((uint)i >= (uint)entries.Length)
+ // ValueType: Devirtualize with EqualityComparer<TValue>.Default intrinsic
+ do
{
- break;
- }
+ // Should be a while loop https://github.com/dotnet/coreclr/issues/15476
+ // Test uint in if rather than loop condition to drop range check for following array access
+ if ((uint)i >= (uint)entries.Length)
+ {
+ break;
+ }
- if (entries[i].hashCode == hashCode && EqualityComparer<TKey>.Default.Equals(entries[i].key, key))
- {
- if (behavior == InsertionBehavior.OverwriteExisting)
+ if (entries[i].hashCode == hashCode && EqualityComparer<TKey>.Default.Equals(entries[i].key, key))
{
- entries[i].value = value;
- _version++;
- return true;
+ if (behavior == InsertionBehavior.OverwriteExisting)
+ {
+ entries[i].value = value;
+ _version++;
+ return true;
+ }
+
+ if (behavior == InsertionBehavior.ThrowOnExisting)
+ {
+ ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(key);
+ }
+
+ return false;
}
- if (behavior == InsertionBehavior.ThrowOnExisting)
+ i = entries[i].next;
+ if (collisionCount >= entries.Length)
{
- ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(key);
+ // The chain of entries forms a loop; which means a concurrent update has happened.
+ // Break out of the loop and throw, rather than looping forever.
+ ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
+ }
+ collisionCount++;
+ } while (true);
+ }
+ else
+ {
+ // Object type: Shared Generic, EqualityComparer<TValue>.Default won't devirtualize
+ // https://github.com/dotnet/coreclr/issues/17273
+ // So cache in a local rather than get EqualityComparer per loop iteration
+ EqualityComparer<TKey> defaultComparer = EqualityComparer<TKey>.Default;
+ do
+ {
+ // Should be a while loop https://github.com/dotnet/coreclr/issues/15476
+ // Test uint in if rather than loop condition to drop range check for following array access
+ if ((uint)i >= (uint)entries.Length)
+ {
+ break;
}
- return false;
- }
+ if (entries[i].hashCode == hashCode && defaultComparer.Equals(entries[i].key, key))
+ {
+ if (behavior == InsertionBehavior.OverwriteExisting)
+ {
+ entries[i].value = value;
+ _version++;
+ return true;
+ }
+
+ if (behavior == InsertionBehavior.ThrowOnExisting)
+ {
+ ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(key);
+ }
+
+ return false;
+ }
- i = entries[i].next;
- collisionCount++;
- } while (true);
+ i = entries[i].next;
+ if (collisionCount >= entries.Length)
+ {
+ // The chain of entries forms a loop; which means a concurrent update has happened.
+ // Break out of the loop and throw, rather than looping forever.
+ ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
+ }
+ collisionCount++;
+ } while (true);
+ }
}
else
{
@@ -505,14 +607,17 @@ namespace System.Collections.Generic
}
i = entries[i].next;
+ if (collisionCount >= entries.Length)
+ {
+ // The chain of entries forms a loop; which means a concurrent update has happened.
+ // Break out of the loop and throw, rather than looping forever.
+ ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
+ }
collisionCount++;
} while (true);
}
- // Can be improved with "Ref Local Reassignment"
- // https://github.com/dotnet/csharplang/blob/master/proposals/ref-local-reassignment.md
- bool resized = false;
bool updateFreeList = false;
int index;
if (_freeCount > 0)
@@ -527,14 +632,13 @@ namespace System.Collections.Generic
if (count == entries.Length)
{
Resize();
- resized = true;
+ bucket = ref _buckets[hashCode % _buckets.Length];
}
index = count;
_count = count + 1;
entries = _entries;
}
- ref int targetBucket = ref resized ? ref _buckets[hashCode % _buckets.Length] : ref bucket;
ref Entry entry = ref entries[index];
if (updateFreeList)
@@ -543,11 +647,11 @@ namespace System.Collections.Generic
}
entry.hashCode = hashCode;
// Value in _buckets is 1-based
- entry.next = targetBucket - 1;
+ entry.next = bucket - 1;
entry.key = key;
entry.value = value;
// Value in _buckets is 1-based
- targetBucket = index + 1;
+ bucket = index + 1;
_version++;
#if !MONO
@@ -566,8 +670,7 @@ namespace System.Collections.Generic
public virtual void OnDeserialization(object sender)
{
- SerializationInfo siInfo;
- HashHelpers.SerializationInfoTable.TryGetValue(this, out siInfo);
+ HashHelpers.SerializationInfoTable.TryGetValue(this, out SerializationInfo siInfo);
if (siInfo == null)
{
@@ -611,9 +714,7 @@ namespace System.Collections.Generic
}
private void Resize()
- {
- Resize(HashHelpers.ExpandPrime(_count), false);
- }
+ => Resize(HashHelpers.ExpandPrime(_count), false);
private void Resize(int newSize, bool forceNewHashCodes)
{
@@ -665,47 +766,56 @@ namespace System.Collections.Generic
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
- if (_buckets != null)
+ int[] buckets = _buckets;
+ Entry[] entries = _entries;
+ int collisionCount = 0;
+ if (buckets != null)
{
int hashCode = (_comparer?.GetHashCode(key) ?? key.GetHashCode()) & 0x7FFFFFFF;
- int bucket = hashCode % _buckets.Length;
+ int bucket = hashCode % buckets.Length;
int last = -1;
- // Value in _buckets is 1-based
- int i = _buckets[bucket] - 1;
+ // Value in buckets is 1-based
+ int i = buckets[bucket] - 1;
while (i >= 0)
{
- ref Entry entry = ref _entries[i];
+ ref Entry entry = ref entries[i];
if (entry.hashCode == hashCode && (_comparer?.Equals(entry.key, key) ?? EqualityComparer<TKey>.Default.Equals(entry.key, key)))
{
if (last < 0)
{
- // Value in _buckets is 1-based
- _buckets[bucket] = entry.next + 1;
+ // Value in buckets is 1-based
+ buckets[bucket] = entry.next + 1;
}
else
{
- _entries[last].next = entry.next;
+ entries[last].next = entry.next;
}
entry.hashCode = -1;
entry.next = _freeList;
if (RuntimeHelpers.IsReferenceOrContainsReferences<TKey>())
{
- entry.key = default(TKey);
+ entry.key = default;
}
if (RuntimeHelpers.IsReferenceOrContainsReferences<TValue>())
{
- entry.value = default(TValue);
+ entry.value = default;
}
_freeList = i;
_freeCount++;
- _version++;
return true;
}
last = i;
i = entry.next;
+ if (collisionCount >= entries.Length)
+ {
+ // The chain of entries forms a loop; which means a concurrent update has happened.
+ // Break out of the loop and throw, rather than looping forever.
+ ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
+ }
+ collisionCount++;
}
}
return false;
@@ -721,27 +831,30 @@ namespace System.Collections.Generic
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
- if (_buckets != null)
+ int[] buckets = _buckets;
+ Entry[] entries = _entries;
+ int collisionCount = 0;
+ if (buckets != null)
{
int hashCode = (_comparer?.GetHashCode(key) ?? key.GetHashCode()) & 0x7FFFFFFF;
- int bucket = hashCode % _buckets.Length;
+ int bucket = hashCode % buckets.Length;
int last = -1;
- // Value in _buckets is 1-based
- int i = _buckets[bucket] - 1;
+ // Value in buckets is 1-based
+ int i = buckets[bucket] - 1;
while (i >= 0)
{
- ref Entry entry = ref _entries[i];
+ ref Entry entry = ref entries[i];
if (entry.hashCode == hashCode && (_comparer?.Equals(entry.key, key) ?? EqualityComparer<TKey>.Default.Equals(entry.key, key)))
{
if (last < 0)
{
- // Value in _buckets is 1-based
- _buckets[bucket] = entry.next + 1;
+ // Value in buckets is 1-based
+ buckets[bucket] = entry.next + 1;
}
else
{
- _entries[last].next = entry.next;
+ entries[last].next = entry.next;
}
value = entry.value;
@@ -751,23 +864,29 @@ namespace System.Collections.Generic
if (RuntimeHelpers.IsReferenceOrContainsReferences<TKey>())
{
- entry.key = default(TKey);
+ entry.key = default;
}
if (RuntimeHelpers.IsReferenceOrContainsReferences<TValue>())
{
- entry.value = default(TValue);
+ entry.value = default;
}
_freeList = i;
_freeCount++;
- _version++;
return true;
}
last = i;
i = entry.next;
+ if (collisionCount >= entries.Length)
+ {
+ // The chain of entries forms a loop; which means a concurrent update has happened.
+ // Break out of the loop and throw, rather than looping forever.
+ ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
+ }
+ collisionCount++;
}
}
- value = default(TValue);
+ value = default;
return false;
}
@@ -779,57 +898,37 @@ namespace System.Collections.Generic
value = _entries[i].value;
return true;
}
- value = default(TValue);
+ value = default;
return false;
}
- public bool TryAdd(TKey key, TValue value) => TryInsert(key, value, InsertionBehavior.None);
+ public bool TryAdd(TKey key, TValue value)
+ => TryInsert(key, value, InsertionBehavior.None);
- bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
- {
- get { return false; }
- }
+ bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => false;
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
- {
- CopyTo(array, index);
- }
+ => CopyTo(array, index);
void ICollection.CopyTo(Array array, int index)
{
if (array == null)
- {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
- }
-
if (array.Rank != 1)
- {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
- }
-
if (array.GetLowerBound(0) != 0)
- {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
- }
-
- if (index < 0 || index > array.Length)
- {
+ if ((uint)index > (uint)array.Length)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
- }
-
if (array.Length - index < Count)
- {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
- }
- KeyValuePair<TKey, TValue>[] pairs = array as KeyValuePair<TKey, TValue>[];
- if (pairs != null)
+ if (array is KeyValuePair<TKey, TValue>[] pairs)
{
CopyTo(pairs, index);
}
- else if (array is DictionaryEntry[])
+ else if (array is DictionaryEntry[] dictEntryArray)
{
- DictionaryEntry[] dictEntryArray = array as DictionaryEntry[];
Entry[] entries = _entries;
for (int i = 0; i < _count; i++)
{
@@ -867,9 +966,7 @@ namespace System.Collections.Generic
}
IEnumerator IEnumerable.GetEnumerator()
- {
- return new Enumerator(this, Enumerator.KeyValuePair);
- }
+ => new Enumerator(this, Enumerator.KeyValuePair);
/// <summary>
/// Ensures that the dictionary can hold up to 'capacity' entries without any further expansion of its backing storage
@@ -881,6 +978,7 @@ namespace System.Collections.Generic
int currentCapacity = _entries == null ? 0 : _entries.Length;
if (currentCapacity >= capacity)
return currentCapacity;
+ _version++;
if (_buckets == null)
return Initialize(capacity);
int newSize = HashHelpers.GetPrime(capacity);
@@ -900,9 +998,7 @@ namespace System.Collections.Generic
/// dictionary.TrimExcess();
/// </summary>
public void TrimExcess()
- {
- TrimExcess(Count);
- }
+ => TrimExcess(Count);
/// <summary>
/// Sets the capacity of this dictionary to hold up 'capacity' entries without any further expansion of its backing storage
@@ -922,6 +1018,7 @@ namespace System.Collections.Generic
return;
int oldCount = _count;
+ _version++;
Initialize(newSize);
Entry[] entries = _entries;
int[] buckets = _buckets;
@@ -945,10 +1042,7 @@ namespace System.Collections.Generic
_freeCount = 0;
}
- bool ICollection.IsSynchronized
- {
- get { return false; }
- }
+ bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot
{
@@ -956,31 +1050,19 @@ namespace System.Collections.Generic
{
if (_syncRoot == null)
{
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ Interlocked.CompareExchange<object>(ref _syncRoot, new object(), null);
}
return _syncRoot;
}
}
- bool IDictionary.IsFixedSize
- {
- get { return false; }
- }
+ bool IDictionary.IsFixedSize => false;
- bool IDictionary.IsReadOnly
- {
- get { return false; }
- }
+ bool IDictionary.IsReadOnly => false;
- ICollection IDictionary.Keys
- {
- get { return (ICollection)Keys; }
- }
+ ICollection IDictionary.Keys => (ICollection)Keys;
- ICollection IDictionary.Values
- {
- get { return (ICollection)Values; }
- }
+ ICollection IDictionary.Values => (ICollection)Values;
object IDictionary.this[object key]
{
@@ -1070,9 +1152,7 @@ namespace System.Collections.Generic
}
IDictionaryEnumerator IDictionary.GetEnumerator()
- {
- return new Enumerator(this, Enumerator.DictEntry);
- }
+ => new Enumerator(this, Enumerator.DictEntry);
void IDictionary.Remove(object key)
{
@@ -1088,11 +1168,11 @@ namespace System.Collections.Generic
public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>,
IDictionaryEnumerator
{
- private Dictionary<TKey, TValue> _dictionary;
- private int _version;
+ private readonly Dictionary<TKey, TValue> _dictionary;
+ private readonly int _version;
private int _index;
private KeyValuePair<TKey, TValue> _current;
- private int _getEnumeratorRetType; // What should Enumerator.Current return?
+ private readonly int _getEnumeratorRetType; // What should Enumerator.Current return?
internal const int DictEntry = 1;
internal const int KeyValuePair = 2;
@@ -1114,7 +1194,7 @@ namespace System.Collections.Generic
}
// Use unsigned comparison since we set index to dictionary.count+1 when the enumeration ends.
- // dictionary.count+1 could be negative if dictionary.count is Int32.MaxValue
+ // dictionary.count+1 could be negative if dictionary.count is int.MaxValue
while ((uint)_index < (uint)_dictionary._count)
{
ref Entry entry = ref _dictionary._entries[_index++];
@@ -1131,10 +1211,7 @@ namespace System.Collections.Generic
return false;
}
- public KeyValuePair<TKey, TValue> Current
- {
- get { return _current; }
- }
+ public KeyValuePair<TKey, TValue> Current => _current;
public void Dispose()
{
@@ -1151,7 +1228,7 @@ namespace System.Collections.Generic
if (_getEnumeratorRetType == DictEntry)
{
- return new System.Collections.DictionaryEntry(_current.Key, _current.Value);
+ return new DictionaryEntry(_current.Key, _current.Value);
}
else
{
@@ -1230,9 +1307,7 @@ namespace System.Collections.Generic
}
public Enumerator GetEnumerator()
- {
- return new Enumerator(_dictionary);
- }
+ => new Enumerator(_dictionary);
public void CopyTo(TKey[] array, int index)
{
@@ -1259,30 +1334,18 @@ namespace System.Collections.Generic
}
}
- public int Count
- {
- get { return _dictionary.Count; }
- }
+ public int Count => _dictionary.Count;
- bool ICollection<TKey>.IsReadOnly
- {
- get { return true; }
- }
+ bool ICollection<TKey>.IsReadOnly => true;
void ICollection<TKey>.Add(TKey item)
- {
- ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
- }
+ => ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
void ICollection<TKey>.Clear()
- {
- ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
- }
+ => ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
bool ICollection<TKey>.Contains(TKey item)
- {
- return _dictionary.ContainsKey(item);
- }
+ => _dictionary.ContainsKey(item);
bool ICollection<TKey>.Remove(TKey item)
{
@@ -1291,44 +1354,25 @@ namespace System.Collections.Generic
}
IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator()
- {
- return new Enumerator(_dictionary);
- }
+ => new Enumerator(_dictionary);
IEnumerator IEnumerable.GetEnumerator()
- {
- return new Enumerator(_dictionary);
- }
+ => new Enumerator(_dictionary);
void ICollection.CopyTo(Array array, int index)
{
if (array == null)
- {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
- }
-
if (array.Rank != 1)
- {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
- }
-
if (array.GetLowerBound(0) != 0)
- {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
- }
-
- if (index < 0 || index > array.Length)
- {
+ if ((uint)index > (uint)array.Length)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
- }
-
if (array.Length - index < _dictionary.Count)
- {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
- }
- TKey[] keys = array as TKey[];
- if (keys != null)
+ if (array is TKey[] keys)
{
CopyTo(keys, index);
}
@@ -1356,24 +1400,18 @@ namespace System.Collections.Generic
}
}
- bool ICollection.IsSynchronized
- {
- get { return false; }
- }
+ bool ICollection.IsSynchronized => false;
- object ICollection.SyncRoot
- {
- get { return ((ICollection)_dictionary).SyncRoot; }
- }
+ object ICollection.SyncRoot => ((ICollection)_dictionary).SyncRoot;
#if MONO
[Serializable]
#endif
- public struct Enumerator : IEnumerator<TKey>, System.Collections.IEnumerator
+ public struct Enumerator : IEnumerator<TKey>, IEnumerator
{
- private Dictionary<TKey, TValue> _dictionary;
+ private readonly Dictionary<TKey, TValue> _dictionary;
private int _index;
- private int _version;
+ private readonly int _version;
private TKey _currentKey;
internal Enumerator(Dictionary<TKey, TValue> dictionary)
@@ -1381,7 +1419,7 @@ namespace System.Collections.Generic
_dictionary = dictionary;
_version = dictionary._version;
_index = 0;
- _currentKey = default(TKey);
+ _currentKey = default;
}
public void Dispose()
@@ -1407,19 +1445,13 @@ namespace System.Collections.Generic
}
_index = _dictionary._count + 1;
- _currentKey = default(TKey);
+ _currentKey = default;
return false;
}
- public TKey Current
- {
- get
- {
- return _currentKey;
- }
- }
+ public TKey Current => _currentKey;
- object System.Collections.IEnumerator.Current
+ object IEnumerator.Current
{
get
{
@@ -1432,7 +1464,7 @@ namespace System.Collections.Generic
}
}
- void System.Collections.IEnumerator.Reset()
+ void IEnumerator.Reset()
{
if (_version != _dictionary._version)
{
@@ -1440,7 +1472,7 @@ namespace System.Collections.Generic
}
_index = 0;
- _currentKey = default(TKey);
+ _currentKey = default;
}
}
}
@@ -1464,9 +1496,7 @@ namespace System.Collections.Generic
}
public Enumerator GetEnumerator()
- {
- return new Enumerator(_dictionary);
- }
+ => new Enumerator(_dictionary);
public void CopyTo(TValue[] array, int index)
{
@@ -1493,20 +1523,12 @@ namespace System.Collections.Generic
}
}
- public int Count
- {
- get { return _dictionary.Count; }
- }
+ public int Count => _dictionary.Count;
- bool ICollection<TValue>.IsReadOnly
- {
- get { return true; }
- }
+ bool ICollection<TValue>.IsReadOnly => true;
void ICollection<TValue>.Add(TValue item)
- {
- ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
- }
+ => ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
bool ICollection<TValue>.Remove(TValue item)
{
@@ -1515,52 +1537,31 @@ namespace System.Collections.Generic
}
void ICollection<TValue>.Clear()
- {
- ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
- }
+ => ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
bool ICollection<TValue>.Contains(TValue item)
- {
- return _dictionary.ContainsValue(item);
- }
+ => _dictionary.ContainsValue(item);
IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator()
- {
- return new Enumerator(_dictionary);
- }
+ => new Enumerator(_dictionary);
IEnumerator IEnumerable.GetEnumerator()
- {
- return new Enumerator(_dictionary);
- }
+ => new Enumerator(_dictionary);
void ICollection.CopyTo(Array array, int index)
{
if (array == null)
- {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
- }
-
if (array.Rank != 1)
- {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
- }
-
if (array.GetLowerBound(0) != 0)
- {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
- }
-
- if (index < 0 || index > array.Length)
- {
+ if ((uint)index > (uint)array.Length)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
- }
-
if (array.Length - index < _dictionary.Count)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
- TValue[] values = array as TValue[];
- if (values != null)
+ if (array is TValue[] values)
{
CopyTo(values, index);
}
@@ -1588,24 +1589,18 @@ namespace System.Collections.Generic
}
}
- bool ICollection.IsSynchronized
- {
- get { return false; }
- }
+ bool ICollection.IsSynchronized => false;
- object ICollection.SyncRoot
- {
- get { return ((ICollection)_dictionary).SyncRoot; }
- }
+ object ICollection.SyncRoot => ((ICollection)_dictionary).SyncRoot;
#if MONO
[Serializable]
#endif
- public struct Enumerator : IEnumerator<TValue>, System.Collections.IEnumerator
+ public struct Enumerator : IEnumerator<TValue>, IEnumerator
{
- private Dictionary<TKey, TValue> _dictionary;
+ private readonly Dictionary<TKey, TValue> _dictionary;
private int _index;
- private int _version;
+ private readonly int _version;
private TValue _currentValue;
internal Enumerator(Dictionary<TKey, TValue> dictionary)
@@ -1613,7 +1608,7 @@ namespace System.Collections.Generic
_dictionary = dictionary;
_version = dictionary._version;
_index = 0;
- _currentValue = default(TValue);
+ _currentValue = default;
}
public void Dispose()
@@ -1638,19 +1633,13 @@ namespace System.Collections.Generic
}
}
_index = _dictionary._count + 1;
- _currentValue = default(TValue);
+ _currentValue = default;
return false;
}
- public TValue Current
- {
- get
- {
- return _currentValue;
- }
- }
+ public TValue Current => _currentValue;
- object System.Collections.IEnumerator.Current
+ object IEnumerator.Current
{
get
{
@@ -1663,14 +1652,14 @@ namespace System.Collections.Generic
}
}
- void System.Collections.IEnumerator.Reset()
+ void IEnumerator.Reset()
{
if (_version != _dictionary._version)
{
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
_index = 0;
- _currentValue = default(TValue);
+ _currentValue = default;
}
}
}