summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Collections
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Collections')
-rw-r--r--src/mscorlib/src/System/Collections/ArrayList.cs453
-rw-r--r--src/mscorlib/src/System/Collections/CollectionBase.cs199
-rw-r--r--src/mscorlib/src/System/Collections/Comparer.cs64
-rw-r--r--src/mscorlib/src/System/Collections/CompatibleComparer.cs44
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs10
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs6
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs18
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs2
-rw-r--r--src/mscorlib/src/System/Collections/DictionaryEntry.cs62
-rw-r--r--src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs182
-rw-r--r--src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs113
-rw-r--r--src/mscorlib/src/System/Collections/Generic/Comparer.cs127
-rw-r--r--src/mscorlib/src/System/Collections/Generic/ComparerHelpers.cs210
-rw-r--r--src/mscorlib/src/System/Collections/Generic/DebugView.cs120
-rw-r--r--src/mscorlib/src/System/Collections/Generic/Dictionary.cs1060
-rw-r--r--src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs290
-rw-r--r--src/mscorlib/src/System/Collections/Generic/ICollection.cs52
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IComparer.cs30
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IDictionary.cs58
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IEnumerable.cs38
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IEnumerator.cs35
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IEqualityComparer.cs19
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IList.cs54
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IReadOnlyCollection.cs34
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IReadOnlyDictionary.cs29
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IReadOnlyList.cs34
-rw-r--r--src/mscorlib/src/System/Collections/Generic/KeyNotFoundException.cs44
-rw-r--r--src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs74
-rw-r--r--src/mscorlib/src/System/Collections/Generic/List.cs754
-rw-r--r--src/mscorlib/src/System/Collections/Hashtable.cs970
-rw-r--r--src/mscorlib/src/System/Collections/ICollection.cs80
-rw-r--r--src/mscorlib/src/System/Collections/IComparer.cs31
-rw-r--r--src/mscorlib/src/System/Collections/IDictionary.cs68
-rw-r--r--src/mscorlib/src/System/Collections/IDictionaryEnumerator.cs78
-rw-r--r--src/mscorlib/src/System/Collections/IEnumerable.cs33
-rw-r--r--src/mscorlib/src/System/Collections/IEnumerator.cs52
-rw-r--r--src/mscorlib/src/System/Collections/IEqualityComparer.cs26
-rw-r--r--src/mscorlib/src/System/Collections/IHashCodeProvider.cs12
-rw-r--r--src/mscorlib/src/System/Collections/IList.cs70
-rw-r--r--src/mscorlib/src/System/Collections/IStructuralComparable.cs11
-rw-r--r--src/mscorlib/src/System/Collections/IStructuralEquatable.cs10
-rw-r--r--src/mscorlib/src/System/Collections/ListDictionaryInternal.cs404
-rw-r--r--src/mscorlib/src/System/Collections/ObjectModel/Collection.cs303
-rw-r--r--src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs244
-rw-r--r--src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs196
-rw-r--r--src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs371
-rw-r--r--src/mscorlib/src/System/Collections/StructuralComparisons.cs89
47 files changed, 3496 insertions, 3767 deletions
diff --git a/src/mscorlib/src/System/Collections/ArrayList.cs b/src/mscorlib/src/System/Collections/ArrayList.cs
index 53746e224e..cee7be726a 100644
--- a/src/mscorlib/src/System/Collections/ArrayList.cs
+++ b/src/mscorlib/src/System/Collections/ArrayList.cs
@@ -14,16 +14,18 @@
**
**
===========================================================*/
-namespace System.Collections {
- using System;
- using System.Runtime;
- using System.Security;
- using System.Diagnostics;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
+using System;
+using System.Runtime;
+using System.Security;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+
+namespace System.Collections
+{
// Implements a variable-size List that uses an array of objects to store the
// elements. A ArrayList has a capacity, which is the allocated length
// of the internal array. As elements are added to a ArrayList, the capacity
@@ -31,7 +33,7 @@ namespace System.Collections {
// internal array.
//
[FriendAccessAllowed]
- [DebuggerTypeProxy(typeof(System.Collections.ArrayList.ArrayListDebugView))]
+ [DebuggerTypeProxy(typeof(System.Collections.ArrayList.ArrayListDebugView))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
internal class ArrayList : IList, ICloneable
@@ -42,38 +44,41 @@ namespace System.Collections {
private int _version;
[NonSerialized]
private Object _syncRoot;
-
+
private const int _defaultCapacity = 4;
- private static readonly Object[] emptyArray = EmptyArray<Object>.Value;
+ private static readonly Object[] emptyArray = Array.Empty<Object>();
// Constructs a ArrayList. The list is initially empty and has a capacity
// of zero. Upon adding the first element to the list the capacity is
// increased to _defaultCapacity, and then increased in multiples of two as required.
- public ArrayList() {
- _items = emptyArray;
+ public ArrayList()
+ {
+ _items = emptyArray;
}
-
+
// Constructs a ArrayList with a given initial capacity. The list is
// initially empty, but will have room for the given number of elements
// before any reallocations are required.
//
- public ArrayList(int capacity) {
- if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", nameof(capacity)));
- Contract.EndContractBlock();
-
- if (capacity == 0)
- _items = emptyArray;
- else
- _items = new Object[capacity];
+ public ArrayList(int capacity)
+ {
+ if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity), SR.Format(SR.ArgumentOutOfRange_MustBeNonNegNum, nameof(capacity)));
+ Contract.EndContractBlock();
+
+ if (capacity == 0)
+ _items = emptyArray;
+ else
+ _items = new Object[capacity];
}
-
+
// Constructs a ArrayList, copying the contents of the given collection. The
// size and capacity of the new list will both be equal to the size of the
// given collection.
//
- public ArrayList(ICollection c) {
- if (c==null)
- throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection"));
+ public ArrayList(ICollection c)
+ {
+ if (c == null)
+ throw new ArgumentNullException(nameof(c), SR.ArgumentNull_Collection);
Contract.EndContractBlock();
int count = c.Count;
@@ -81,124 +86,147 @@ namespace System.Collections {
{
_items = emptyArray;
}
- else {
+ else
+ {
_items = new Object[count];
AddRange(c);
}
}
-
+
// Gets and sets the capacity of this list. The capacity is the size of
// the internal array used to hold items. When set, the internal
// array of the list is reallocated to the given capacity.
//
- public virtual int Capacity {
- get {
+ public virtual int Capacity
+ {
+ get
+ {
Contract.Ensures(Contract.Result<int>() >= Count);
return _items.Length;
}
- set {
- if (value < _size) {
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
+ set
+ {
+ if (value < _size)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_SmallCapacity);
}
Contract.Ensures(Capacity >= 0);
Contract.EndContractBlock();
// We don't want to update the version number when we change the capacity.
// Some existing applications have dependency on this.
- if (value != _items.Length) {
- if (value > 0) {
+ if (value != _items.Length)
+ {
+ if (value > 0)
+ {
Object[] newItems = new Object[value];
- if (_size > 0) {
+ if (_size > 0)
+ {
Array.Copy(_items, 0, newItems, 0, _size);
}
_items = newItems;
}
- else {
+ else
+ {
_items = new Object[_defaultCapacity];
}
- }
+ }
}
}
// Read-only property describing how many elements are in the List.
- public virtual int Count {
- get {
+ public virtual int Count
+ {
+ get
+ {
Contract.Ensures(Contract.Result<int>() >= 0);
return _size;
}
}
- public virtual bool IsFixedSize {
+ public virtual bool IsFixedSize
+ {
get { return false; }
}
-
+
// Is this ArrayList read-only?
- public virtual bool IsReadOnly {
+ public virtual bool IsReadOnly
+ {
get { return false; }
}
// Is this ArrayList synchronized (thread-safe)?
- public virtual bool IsSynchronized {
+ public virtual bool IsSynchronized
+ {
get { return false; }
}
-
+
// Synchronization root for this object.
- public virtual Object SyncRoot {
- get {
- if( _syncRoot == null) {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ public virtual Object SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
- return _syncRoot;
+ return _syncRoot;
}
}
-
+
// Sets or Gets the element at the given index.
//
- public virtual Object this[int index] {
- get {
- if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ public virtual Object this[int index]
+ {
+ get
+ {
+ if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
Contract.EndContractBlock();
return _items[index];
}
- set {
- if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ set
+ {
+ if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
Contract.EndContractBlock();
_items[index] = value;
_version++;
}
}
-
+
// Adds the given object to the end of this list. The size of the list is
// increased by one. If required, the capacity of the list is doubled
// before adding the new element.
//
- public virtual int Add(Object value) {
+ public virtual int Add(Object value)
+ {
Contract.Ensures(Contract.Result<int>() >= 0);
if (_size == _items.Length) EnsureCapacity(_size + 1);
_items[_size] = value;
_version++;
return _size++;
}
-
+
// Adds the elements of the given collection to the end of this list. If
// required, the capacity of the list is increased to twice the previous
// capacity or the new size, whichever is larger.
//
- public virtual void AddRange(ICollection c) {
+ public virtual void AddRange(ICollection c)
+ {
InsertRange(_size, c);
}
-
+
// Clears the contents of ArrayList.
- public virtual void Clear() {
+ public virtual void Clear()
+ {
if (_size > 0)
{
- Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
- _size = 0;
+ Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
+ _size = 0;
}
_version++;
}
-
+
// Clones this ArrayList, doing a shallow copy. (A copy is made of all
// Object references in the ArrayList, but the Objects pointed to
// are not cloned).
@@ -211,22 +239,25 @@ namespace System.Collections {
Array.Copy(_items, 0, la._items, 0, _size);
return la;
}
-
-
+
+
// Contains returns true if the specified element is in the ArrayList.
// It does a linear, O(n) search. Equality is determined by calling
// item.Equals().
//
- public virtual bool Contains(Object item) {
- if (item==null) {
- for(int i=0; i<_size; i++)
- if (_items[i]==null)
+ public virtual bool Contains(Object item)
+ {
+ if (item == null)
+ {
+ for (int i = 0; i < _size; i++)
+ if (_items[i] == null)
return true;
return false;
}
- else {
- for(int i=0; i<_size; i++)
- if ( (_items[i] != null) && (_items[i].Equals(item)) )
+ else
+ {
+ for (int i = 0; i < _size; i++)
+ if ((_items[i] != null) && (_items[i].Equals(item)))
return true;
return false;
}
@@ -235,9 +266,10 @@ namespace System.Collections {
// Copies this ArrayList into array, which must be of a
// compatible array type.
//
- public virtual void CopyTo(Array array, int arrayIndex) {
+ public virtual void CopyTo(Array array, int arrayIndex)
+ {
if ((array != null) && (array.Rank != 1))
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
Contract.EndContractBlock();
// Delegate rest of error checking to Array.Copy.
Array.Copy(_items, 0, array, arrayIndex, _size);
@@ -247,9 +279,11 @@ namespace System.Collections {
// value. If the currect capacity of the list is less than min, the
// capacity is increased to twice the current capacity or to min,
// whichever is larger.
- private void EnsureCapacity(int min) {
- if (_items.Length < min) {
- int newCapacity = _items.Length == 0? _defaultCapacity: _items.Length * 2;
+ private void EnsureCapacity(int min)
+ {
+ if (_items.Length < min)
+ {
+ int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Length * 2;
// Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow.
// Note that this check works even when _items.Length overflowed thanks to the (uint) cast
if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength;
@@ -257,17 +291,18 @@ namespace System.Collections {
Capacity = newCapacity;
}
}
-
+
// Returns an enumerator for this list with the given
// permission for removal of elements. If modifications made to the list
// while an enumeration is in progress, the MoveNext and
// GetObject methods of the enumerator will throw an exception.
//
- public virtual IEnumerator GetEnumerator() {
+ public virtual IEnumerator GetEnumerator()
+ {
Contract.Ensures(Contract.Result<IEnumerator>() != null);
return new ArrayListEnumeratorSimple(this);
}
-
+
// Returns the index of the first occurrence of a given value in a range of
// this list. The list is searched forwards from beginning to end.
// The elements of the list are compared to the given value using the
@@ -276,47 +311,53 @@ namespace System.Collections {
// This method uses the Array.IndexOf method to perform the
// search.
//
- public virtual int IndexOf(Object value) {
+ public virtual int IndexOf(Object value)
+ {
Contract.Ensures(Contract.Result<int>() < Count);
return Array.IndexOf((Array)_items, value, 0, _size);
}
-
+
// Inserts an element into this list at a given index. The size of the list
// is increased by one. If required, the capacity of the list is doubled
// before inserting the new element.
//
- public virtual void Insert(int index, Object value) {
+ public virtual void Insert(int index, Object value)
+ {
// Note that insertions at the end are legal.
- if (index < 0 || index > _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_ArrayListInsert"));
+ if (index < 0 || index > _size) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_ArrayListInsert);
//Contract.Ensures(Count == Contract.OldValue(Count) + 1);
Contract.EndContractBlock();
if (_size == _items.Length) EnsureCapacity(_size + 1);
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index, _items, index + 1, _size - index);
}
_items[index] = value;
_size++;
_version++;
}
-
+
// Inserts the elements of the given collection at a given index. If
// required, the capacity of the list is increased to twice the previous
// capacity or the new size, whichever is larger. Ranges may be added
// to the end of the list by setting index to the ArrayList's size.
//
- public virtual void InsertRange(int index, ICollection c) {
- if (c==null)
- throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection"));
- if (index < 0 || index > _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ public virtual void InsertRange(int index, ICollection c)
+ {
+ if (c == null)
+ throw new ArgumentNullException(nameof(c), SR.ArgumentNull_Collection);
+ if (index < 0 || index > _size) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
//Contract.Ensures(Count == Contract.OldValue(Count) + c.Count);
Contract.EndContractBlock();
int count = c.Count;
- if (count > 0) {
- EnsureCapacity(_size + count);
+ if (count > 0)
+ {
+ EnsureCapacity(_size + count);
// shift existing items
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index, _items, index + count, _size - index);
}
@@ -327,54 +368,59 @@ namespace System.Collections {
_version++;
}
}
-
+
// Returns a read-only IList wrapper for the given IList.
//
[FriendAccessAllowed]
- public static IList ReadOnly(IList list) {
- if (list==null)
+ public static IList ReadOnly(IList list)
+ {
+ if (list == null)
throw new ArgumentNullException(nameof(list));
Contract.Ensures(Contract.Result<IList>() != null);
Contract.EndContractBlock();
return new ReadOnlyList(list);
}
-
+
// Removes the element at the given index. The size of the list is
// decreased by one.
//
- public virtual void Remove(Object obj) {
+ public virtual void Remove(Object obj)
+ {
Contract.Ensures(Count >= 0);
int index = IndexOf(obj);
- BCLDebug.Correctness(index >= 0 || !(obj is Int32), "You passed an Int32 to Remove that wasn't in the ArrayList." + Environment.NewLine + "Did you mean RemoveAt? int: "+obj+" Count: "+Count);
- if (index >=0)
+ BCLDebug.Correctness(index >= 0 || !(obj is Int32), "You passed an Int32 to Remove that wasn't in the ArrayList." + Environment.NewLine + "Did you mean RemoveAt? int: " + obj + " Count: " + Count);
+ if (index >= 0)
RemoveAt(index);
}
-
+
// Removes the element at the given index. The size of the list is
// decreased by one.
//
- public virtual void RemoveAt(int index) {
- if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ public virtual void RemoveAt(int index)
+ {
+ if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
Contract.Ensures(Count >= 0);
//Contract.Ensures(Count == Contract.OldValue(Count) - 1);
Contract.EndContractBlock();
_size--;
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index + 1, _items, index, _size - index);
}
_items[_size] = null;
_version++;
}
-
+
// ToArray returns a new array of a particular type containing the contents
// of the ArrayList. This requires copying the ArrayList and potentially
// downcasting all elements. This copy may fail and is an O(n) operation.
// Internally, this implementation calls Array.Copy.
//
- public virtual Array ToArray(Type type) {
- if (type==null)
+ public virtual Array ToArray(Type type)
+ {
+ if (type == null)
throw new ArgumentNullException(nameof(type));
Contract.Ensures(Contract.Result<Array>() != null);
Contract.EndContractBlock();
@@ -382,84 +428,103 @@ namespace System.Collections {
Array.Copy(_items, 0, array, 0, _size);
return array;
}
-
+
[Serializable]
private class ReadOnlyList : IList
{
private IList _list;
-
- internal ReadOnlyList(IList l) {
+
+ internal ReadOnlyList(IList l)
+ {
_list = l;
}
-
- public virtual int Count {
+
+ public virtual int Count
+ {
get { return _list.Count; }
}
-
- public virtual bool IsReadOnly {
+
+ public virtual bool IsReadOnly
+ {
get { return true; }
}
- public virtual bool IsFixedSize {
+ public virtual bool IsFixedSize
+ {
get { return true; }
}
- public virtual bool IsSynchronized {
+ public virtual bool IsSynchronized
+ {
get { return _list.IsSynchronized; }
}
-
- public virtual Object this[int index] {
- get {
+
+ public virtual Object this[int index]
+ {
+ get
+ {
return _list[index];
}
- set {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
+ set
+ {
+ throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
}
-
- public virtual Object SyncRoot {
+
+ public virtual Object SyncRoot
+ {
get { return _list.SyncRoot; }
}
-
- public virtual int Add(Object obj) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
+
+ public virtual int Add(Object obj)
+ {
+ throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
-
- public virtual void Clear() {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
+
+ public virtual void Clear()
+ {
+ throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
-
- public virtual bool Contains(Object obj) {
+
+ public virtual bool Contains(Object obj)
+ {
return _list.Contains(obj);
}
-
- public virtual void CopyTo(Array array, int index) {
+
+ public virtual void CopyTo(Array array, int index)
+ {
_list.CopyTo(array, index);
}
-
- public virtual IEnumerator GetEnumerator() {
+
+ public virtual IEnumerator GetEnumerator()
+ {
return _list.GetEnumerator();
}
-
- public virtual int IndexOf(Object value) {
+
+ public virtual int IndexOf(Object value)
+ {
return _list.IndexOf(value);
}
-
- public virtual void Insert(int index, Object obj) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
+
+ public virtual void Insert(int index, Object obj)
+ {
+ throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
- public virtual void Remove(Object value) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
+ public virtual void Remove(Object value)
+ {
+ throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
-
- public virtual void RemoveAt(int index) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
+
+ public virtual void RemoveAt(int index)
+ {
+ throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
}
[Serializable]
- private sealed class ArrayListEnumeratorSimple : IEnumerator, ICloneable {
+ private sealed class ArrayListEnumeratorSimple : IEnumerator, ICloneable
+ {
private ArrayList list;
private int index;
private int version;
@@ -467,77 +532,95 @@ namespace System.Collections {
[NonSerialized]
private bool isArrayList;
// this object is used to indicate enumeration has not started or has terminated
- static Object dummyObject = new Object();
-
- internal ArrayListEnumeratorSimple(ArrayList list) {
+ private static Object dummyObject = new Object();
+
+ internal ArrayListEnumeratorSimple(ArrayList list)
+ {
this.list = list;
- this.index = -1;
+ index = -1;
version = list._version;
isArrayList = (list.GetType() == typeof(ArrayList));
- currentElement = dummyObject;
+ currentElement = dummyObject;
}
-
- public Object Clone() {
+
+ public Object Clone()
+ {
return MemberwiseClone();
}
-
- public bool MoveNext() {
- if (version != list._version) {
- throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
+
+ public bool MoveNext()
+ {
+ if (version != list._version)
+ {
+ throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
}
- if( isArrayList) { // avoid calling virtual methods if we are operating on ArrayList to improve performance
- if (index < list._size - 1) {
+ if (isArrayList)
+ { // avoid calling virtual methods if we are operating on ArrayList to improve performance
+ if (index < list._size - 1)
+ {
currentElement = list._items[++index];
return true;
}
- else {
+ else
+ {
currentElement = dummyObject;
- index =list._size;
+ index = list._size;
return false;
- }
+ }
}
- else {
- if (index < list.Count - 1) {
+ else
+ {
+ if (index < list.Count - 1)
+ {
currentElement = list[++index];
return true;
}
- else {
+ else
+ {
index = list.Count;
currentElement = dummyObject;
return false;
}
}
}
-
- public Object Current {
- get {
+
+ public Object Current
+ {
+ get
+ {
object temp = currentElement;
- if(dummyObject == temp) { // check if enumeration has not started or has terminated
- if (index == -1) {
- throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
+ if (dummyObject == temp)
+ { // check if enumeration has not started or has terminated
+ if (index == -1)
+ {
+ throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
}
- else {
- throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));
+ else
+ {
+ throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumEnded));
}
}
return temp;
}
}
-
- public void Reset() {
- if (version != list._version) {
- throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
- }
-
+
+ public void Reset()
+ {
+ if (version != list._version)
+ {
+ throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
+ }
+
currentElement = dummyObject;
index = -1;
}
}
- internal class ArrayListDebugView {
- private ArrayList arrayList;
+ internal class ArrayListDebugView
+ {
+ private ArrayList arrayList;
}
- }
+ }
}
diff --git a/src/mscorlib/src/System/Collections/CollectionBase.cs b/src/mscorlib/src/System/Collections/CollectionBase.cs
deleted file mode 100644
index a3dd88a7b3..0000000000
--- a/src/mscorlib/src/System/Collections/CollectionBase.cs
+++ /dev/null
@@ -1,199 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-//
-
-namespace System.Collections {
- using System;
- using System.Diagnostics.Contracts;
-
- // Useful base class for typed read/write collections where items derive from object
- [Serializable]
- public abstract class CollectionBase : IList {
- private ArrayList list;
-
- protected CollectionBase() {
- list = new ArrayList();
- }
-
- internal ArrayList InnerList {
- get {
- if (list == null)
- list = new ArrayList();
- return list;
- }
- }
-
- protected IList List {
- get { return (IList)this; }
- }
-
-
- public int Count {
- get {
- return list == null ? 0 : list.Count;
- }
- }
-
- public void Clear() {
- OnClear();
- InnerList.Clear();
- OnClearComplete();
- }
-
- public void RemoveAt(int index) {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
- Object temp = InnerList[index];
- OnValidate(temp);
- OnRemove(index, temp);
- InnerList.RemoveAt(index);
- try {
- OnRemoveComplete(index, temp);
- }
- catch {
- InnerList.Insert(index, temp);
- throw;
- }
-
- }
-
- bool IList.IsReadOnly {
- get { return InnerList.IsReadOnly; }
- }
-
- bool IList.IsFixedSize {
- get { return InnerList.IsFixedSize; }
- }
-
- bool ICollection.IsSynchronized {
- get { return InnerList.IsSynchronized; }
- }
-
- Object ICollection.SyncRoot {
- get { return InnerList.SyncRoot; }
- }
-
- void ICollection.CopyTo(Array array, int index) {
- InnerList.CopyTo(array, index);
- }
-
- Object IList.this[int index] {
- get {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
- return InnerList[index];
- }
- set {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
- OnValidate(value);
- Object temp = InnerList[index];
- OnSet(index, temp, value);
- InnerList[index] = value;
- try {
- OnSetComplete(index, temp, value);
- }
- catch {
- InnerList[index] = temp;
- throw;
- }
- }
- }
-
- bool IList.Contains(Object value) {
- return InnerList.Contains(value);
- }
-
- int IList.Add(Object value) {
- OnValidate(value);
- OnInsert(InnerList.Count, value);
- int index = InnerList.Add(value);
- try {
- OnInsertComplete(index, value);
- }
- catch {
- InnerList.RemoveAt(index);
- throw;
- }
- return index;
- }
-
-
- void IList.Remove(Object value) {
- OnValidate(value);
- int index = InnerList.IndexOf(value);
- if (index < 0) throw new ArgumentException(Environment.GetResourceString("Arg_RemoveArgNotFound"));
- OnRemove(index, value);
- InnerList.RemoveAt(index);
- try{
- OnRemoveComplete(index, value);
- }
- catch {
- InnerList.Insert(index, value);
- throw;
- }
- }
-
- int IList.IndexOf(Object value) {
- return InnerList.IndexOf(value);
- }
-
- void IList.Insert(int index, Object value) {
- if (index < 0 || index > Count)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
- OnValidate(value);
- OnInsert(index, value);
- InnerList.Insert(index, value);
- try {
- OnInsertComplete(index, value);
- }
- catch {
- InnerList.RemoveAt(index);
- throw;
- }
- }
-
- public IEnumerator GetEnumerator() {
- return InnerList.GetEnumerator();
- }
-
- protected virtual void OnSet(int index, Object oldValue, Object newValue) {
- }
-
- protected virtual void OnInsert(int index, Object value) {
- }
-
- protected virtual void OnClear() {
- }
-
- protected virtual void OnRemove(int index, Object value) {
- }
-
- protected virtual void OnValidate(Object value) {
- if (value == null) throw new ArgumentNullException(nameof(value));
- Contract.EndContractBlock();
- }
-
- protected virtual void OnSetComplete(int index, Object oldValue, Object newValue) {
- }
-
- protected virtual void OnInsertComplete(int index, Object value) {
- }
-
- protected virtual void OnClearComplete() {
- }
-
- protected virtual void OnRemoveComplete(int index, Object value) {
- }
-
- }
-
-}
diff --git a/src/mscorlib/src/System/Collections/Comparer.cs b/src/mscorlib/src/System/Collections/Comparer.cs
index 928b0f9f9a..7f4f9f0a07 100644
--- a/src/mscorlib/src/System/Collections/Comparer.cs
+++ b/src/mscorlib/src/System/Collections/Comparer.cs
@@ -12,46 +12,53 @@
**
**
===========================================================*/
-namespace System.Collections {
-
- using System;
- using System.Globalization;
- using System.Runtime.Serialization;
- using System.Diagnostics.Contracts;
+using System;
+using System.Globalization;
+using System.Runtime.Serialization;
+using System.Diagnostics.Contracts;
+
+namespace System.Collections
+{
[Serializable]
- internal sealed class Comparer : IComparer , ISerializable
+ internal sealed class Comparer : IComparer, ISerializable
{
- private CompareInfo m_compareInfo;
+ private CompareInfo m_compareInfo;
public static readonly Comparer Default = new Comparer(CultureInfo.CurrentCulture);
public static readonly Comparer DefaultInvariant = new Comparer(CultureInfo.InvariantCulture);
-
+
private const String CompareInfoName = "CompareInfo";
- private Comparer() {
+ private Comparer()
+ {
m_compareInfo = null;
}
- public Comparer(CultureInfo culture) {
- if (culture==null) {
+ public Comparer(CultureInfo culture)
+ {
+ if (culture == null)
+ {
throw new ArgumentNullException(nameof(culture));
}
Contract.EndContractBlock();
m_compareInfo = culture.CompareInfo;
}
-
- private Comparer(SerializationInfo info, StreamingContext context) {
+
+ private Comparer(SerializationInfo info, StreamingContext context)
+ {
m_compareInfo = null;
- SerializationInfoEnumerator enumerator = info.GetEnumerator();
- while( enumerator.MoveNext()) {
- switch( enumerator.Name) {
+ SerializationInfoEnumerator enumerator = info.GetEnumerator();
+ while (enumerator.MoveNext())
+ {
+ switch (enumerator.Name)
+ {
case CompareInfoName:
- m_compareInfo = (CompareInfo) info.GetValue(CompareInfoName, typeof(CompareInfo));
+ m_compareInfo = (CompareInfo)info.GetValue(CompareInfoName, typeof(CompareInfo));
break;
}
}
}
-
+
// Compares two Objects by calling CompareTo. If a ==
// b,0 is returned. If a implements
// IComparable, a.CompareTo(b) is returned. If a
@@ -59,11 +66,13 @@ namespace System.Collections {
// -(b.CompareTo(a)) is returned, otherwise an
// exception is thrown.
//
- public int Compare(Object a, Object b) {
+ public int Compare(Object a, Object b)
+ {
if (a == b) return 0;
if (a == null) return -1;
if (b == null) return 1;
- if (m_compareInfo != null) {
+ if (m_compareInfo != null)
+ {
String sa = a as String;
String sb = b as String;
if (sa != null && sb != null)
@@ -78,18 +87,21 @@ namespace System.Collections {
if (ib != null)
return -ib.CompareTo(a);
- throw new ArgumentException(Environment.GetResourceString("Argument_ImplementIComparable"));
+ throw new ArgumentException(SR.Argument_ImplementIComparable);
}
- public void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
- if( m_compareInfo != null) {
+ if (m_compareInfo != null)
+ {
info.AddValue(CompareInfoName, m_compareInfo);
}
- }
+ }
}
}
diff --git a/src/mscorlib/src/System/Collections/CompatibleComparer.cs b/src/mscorlib/src/System/Collections/CompatibleComparer.cs
index e5d3961245..1c90707184 100644
--- a/src/mscorlib/src/System/Collections/CompatibleComparer.cs
+++ b/src/mscorlib/src/System/Collections/CompatibleComparer.cs
@@ -6,39 +6,45 @@
using System.Diagnostics.Contracts;
-namespace System.Collections {
-
+namespace System.Collections
+{
[Serializable]
- internal class CompatibleComparer: IEqualityComparer {
- IComparer _comparer;
+ internal class CompatibleComparer : IEqualityComparer
+ {
+ private IComparer _comparer;
#pragma warning disable 618
- IHashCodeProvider _hcp;
+ private IHashCodeProvider _hcp;
- internal CompatibleComparer(IComparer comparer, IHashCodeProvider hashCodeProvider) {
+ internal CompatibleComparer(IComparer comparer, IHashCodeProvider hashCodeProvider)
+ {
_comparer = comparer;
_hcp = hashCodeProvider;
}
#pragma warning restore 618
- public int Compare(Object a, Object b) {
+ public int Compare(Object a, Object b)
+ {
if (a == b) return 0;
if (a == null) return -1;
if (b == null) return 1;
if (_comparer != null)
- return _comparer.Compare(a,b);
+ return _comparer.Compare(a, b);
IComparable ia = a as IComparable;
if (ia != null)
return ia.CompareTo(b);
- throw new ArgumentException(Environment.GetResourceString("Argument_ImplementIComparable"));
+ throw new ArgumentException(SR.Argument_ImplementIComparable);
}
- public new bool Equals(Object a, Object b) {
- return Compare(a, b) == 0;
+ public new bool Equals(Object a, Object b)
+ {
+ return Compare(a, b) == 0;
}
- public int GetHashCode(Object obj) {
- if( obj == null) {
+ public int GetHashCode(Object obj)
+ {
+ if (obj == null)
+ {
throw new ArgumentNullException(nameof(obj));
}
Contract.EndContractBlock();
@@ -49,16 +55,20 @@ namespace System.Collections {
}
// These are helpers for the Hashtable to query the IKeyComparer infrastructure.
- internal IComparer Comparer {
- get {
+ internal IComparer Comparer
+ {
+ get
+ {
return _comparer;
}
}
// These are helpers for the Hashtable to query the IKeyComparer infrastructure.
#pragma warning disable 618
- internal IHashCodeProvider HashCodeProvider {
- get {
+ internal IHashCodeProvider HashCodeProvider
+ {
+ get
+ {
return _hcp;
}
}
diff --git a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs
index 8b9014a103..436808c439 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs
@@ -65,7 +65,7 @@ namespace System.Collections.Concurrent
private volatile Tables m_tables; // Internal tables of the dictionary
// NOTE: this is only used for compat reasons to serialize the comparer.
// This should not be accessed from anywhere else outside of the serialization methods.
- internal IEqualityComparer<TKey> m_comparer;
+ internal IEqualityComparer<TKey> m_comparer;
private readonly bool m_growLockArray; // Whether to dynamically increase the size of the striped lock
// How many times we resized becaused of collisions.
@@ -102,6 +102,10 @@ namespace System.Collections.Concurrent
private static bool IsValueWriteAtomic()
{
Type valueType = typeof(TValue);
+ if (valueType.IsEnum)
+ {
+ valueType = Enum.GetUnderlyingType(valueType);
+ }
//
// Section 12.6.6 of ECMA CLI explains which types can be read and written atomically without
@@ -705,7 +709,6 @@ namespace System.Collections.Concurrent
{
count += m_tables.m_countPerLock[i];
}
-
}
finally
{
@@ -1404,7 +1407,6 @@ namespace System.Collections.Concurrent
/// </summary>
private static int DefaultConcurrencyLevel
{
-
get { return DEFAULT_CONCURRENCY_MULTIPLIER * PlatformHelper.ProcessorCount; }
}
@@ -1559,7 +1561,7 @@ namespace System.Collections.Concurrent
/// </summary>
private class DictionaryEnumerator : IDictionaryEnumerator
{
- IEnumerator<KeyValuePair<TKey, TValue>> m_enumerator; // Enumerator over the dictionary.
+ private IEnumerator<KeyValuePair<TKey, TValue>> m_enumerator; // Enumerator over the dictionary.
internal DictionaryEnumerator(ConcurrentDictionary<TKey, TValue> dictionary)
{
diff --git a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs
index 90ada007dd..c6211dadd3 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs
@@ -205,7 +205,7 @@ namespace System.Collections.Concurrent
/// cref="ICollection"/>. This property is not supported.
/// </summary>
/// <exception cref="NotSupportedException">The SyncRoot property is not supported.</exception>
- object ICollection.SyncRoot { get { throw new NotSupportedException(Environment.GetResourceString("ConcurrentCollection_SyncRoot_NotSupported")); } }
+ object ICollection.SyncRoot { get { throw new NotSupportedException(SR.ConcurrentCollection_SyncRoot_NotSupported); } }
/// <summary>Returns an enumerator that iterates through a collection.</summary>
/// <returns>An <see cref="IEnumerator"/> that can be used to iterate through the collection.</returns>
@@ -443,7 +443,7 @@ namespace System.Collections.Concurrent
long count = GetCount(head, headHead, tail, tailTail);
if (index > array.Length - count)
{
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
+ throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
}
// Copy the items to the target array
@@ -1115,7 +1115,7 @@ namespace System.Collections.Concurrent
[StructLayout(LayoutKind.Explicit, Size = 192)] // padding before/between/after fields based on typical cache line size of 64
internal struct PaddedHeadAndTail
{
- [FieldOffset(64)] public int Head;
+ [FieldOffset(64)] public int Head;
[FieldOffset(128)] public int Tail;
}
}
diff --git a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs
index 10a5201f6c..82bc4f9f5c 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs
@@ -135,7 +135,7 @@ namespace System.Collections.Concurrent
{
get
{
- throw new NotSupportedException(Environment.GetResourceString("ConcurrentCollection_SyncRoot_NotSupported"));
+ throw new NotSupportedException(SR.ConcurrentCollection_SyncRoot_NotSupported);
}
}
@@ -306,7 +306,6 @@ namespace System.Collections.Concurrent
result = default(T);
return false;
-
}
/// <summary>
@@ -328,7 +327,7 @@ namespace System.Collections.Concurrent
Node head;
Node next;
int backoff = 1;
- Random r = new Random(Environment.TickCount & Int32.MaxValue); // avoid the case where TickCount could return Int32.MinValue
+ Random r = null;
while (true)
{
head = m_head;
@@ -359,7 +358,18 @@ namespace System.Collections.Concurrent
spin.SpinOnce();
}
- backoff = spin.NextSpinWillYield ? r.Next(1, BACKOFF_MAX_YIELDS) : backoff * 2;
+ if (spin.NextSpinWillYield)
+ {
+ if (r == null)
+ {
+ r = new Random();
+ }
+ backoff = r.Next(1, BACKOFF_MAX_YIELDS);
+ }
+ else
+ {
+ backoff *= 2;
+ }
}
}
diff --git a/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs b/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs
index 0347ece0ec..7c585d8b98 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs
@@ -16,7 +16,6 @@ using System.Diagnostics;
namespace System.Collections.Concurrent
{
-
/// <summary>
/// Defines methods to manipulate thread-safe collections intended for producer/consumer usage.
/// </summary>
@@ -64,6 +63,5 @@ namespace System.Collections.Concurrent
internal sealed class SystemCollectionsConcurrent_ProducerConsumerCollectionDebugView<T>
{
private IProducerConsumerCollection<T> m_collection; // The collection being viewed.
-
}
}
diff --git a/src/mscorlib/src/System/Collections/DictionaryEntry.cs b/src/mscorlib/src/System/Collections/DictionaryEntry.cs
deleted file mode 100644
index 0c5d8b2387..0000000000
--- a/src/mscorlib/src/System/Collections/DictionaryEntry.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: DictionaryEntry
-**
-**
-**
-**
-** Purpose: Return Value for IDictionaryEnumerator::GetEntry
-**
-**
-===========================================================*/
-namespace System.Collections {
-
- using System;
- using System.ComponentModel;
- // A DictionaryEntry holds a key and a value from a dictionary.
- // It is returned by IDictionaryEnumerator::GetEntry().
- [Serializable]
- public struct DictionaryEntry
- {
- private Object _key;
- private Object _value;
-
- // Constructs a new DictionaryEnumerator by setting the Key
- // and Value fields appropriately.
- public DictionaryEntry(Object key, Object value) {
- _key = key;
- _value = value;
- }
-
- public Object Key {
- get {
- return _key;
- }
-
- set {
- _key = value;
- }
- }
-
- public Object Value {
- get {
- return _value;
- }
-
- set {
- _value = value;
- }
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out object key, out object value)
- {
- key = Key;
- value = Value;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs b/src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs
index a610fce016..63e0d47c75 100644
--- a/src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs
+++ b/src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs
@@ -15,178 +15,218 @@
using System.Diagnostics.Contracts;
-namespace System.Collections {
+namespace System.Collections
+{
/// This is a simple implementation of IDictionary that is empty and readonly.
[Serializable]
- internal sealed class EmptyReadOnlyDictionaryInternal: IDictionary {
-
+ internal sealed class EmptyReadOnlyDictionaryInternal : IDictionary
+ {
// Note that this class must be agile with respect to AppDomains. See its usage in
// System.Exception to understand why this is the case.
- public EmptyReadOnlyDictionaryInternal() {
+ public EmptyReadOnlyDictionaryInternal()
+ {
}
// IEnumerable members
- IEnumerator IEnumerable.GetEnumerator() {
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return new NodeEnumerator();
}
// ICollection members
- public void CopyTo(Array array, int index) {
- if (array==null)
+ public void CopyTo(Array array, int index)
+ {
+ if (array == null)
throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
- if ( array.Length - index < this.Count )
- throw new ArgumentException( Environment.GetResourceString("ArgumentOutOfRange_Index"), nameof(index));
+ if (array.Length - index < this.Count)
+ throw new ArgumentException(SR.ArgumentOutOfRange_Index, nameof(index));
Contract.EndContractBlock();
// the actual copy is a NOP
}
- public int Count {
- get {
+ public int Count
+ {
+ get
+ {
return 0;
}
- }
+ }
- public Object SyncRoot {
- get {
+ public Object SyncRoot
+ {
+ get
+ {
return this;
}
}
- public bool IsSynchronized {
- get {
+ public bool IsSynchronized
+ {
+ get
+ {
return false;
}
}
// IDictionary members
- public Object this[Object key] {
- get {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public Object this[Object key]
+ {
+ get
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
return null;
}
- set {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ set
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
- if (!key.GetType().IsSerializable)
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(key));
+ if (!key.GetType().IsSerializable)
+ throw new ArgumentException(SR.Argument_NotSerializable, nameof(key));
- if( (value != null) && (!value.GetType().IsSerializable ) )
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(value));
+ if ((value != null) && (!value.GetType().IsSerializable))
+ throw new ArgumentException(SR.Argument_NotSerializable, nameof(value));
Contract.EndContractBlock();
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
}
- public ICollection Keys {
- get {
- return EmptyArray<Object>.Value;
+ public ICollection Keys
+ {
+ get
+ {
+ return Array.Empty<Object>();
}
}
- public ICollection Values {
- get {
- return EmptyArray<Object>.Value;
+ public ICollection Values
+ {
+ get
+ {
+ return Array.Empty<Object>();
}
}
- public bool Contains(Object key) {
+ public bool Contains(Object key)
+ {
return false;
}
- public void Add(Object key, Object value) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public void Add(Object key, Object value)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
- if (!key.GetType().IsSerializable)
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(key) );
+ if (!key.GetType().IsSerializable)
+ throw new ArgumentException(SR.Argument_NotSerializable, nameof(key));
- if( (value != null) && (!value.GetType().IsSerializable) )
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(value));
+ if ((value != null) && (!value.GetType().IsSerializable))
+ throw new ArgumentException(SR.Argument_NotSerializable, nameof(value));
Contract.EndContractBlock();
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
- public void Clear() {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ public void Clear()
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
- public bool IsReadOnly {
- get {
+ public bool IsReadOnly
+ {
+ get
+ {
return true;
}
}
- public bool IsFixedSize {
- get {
+ public bool IsFixedSize
+ {
+ get
+ {
return true;
}
}
- public IDictionaryEnumerator GetEnumerator() {
+ public IDictionaryEnumerator GetEnumerator()
+ {
return new NodeEnumerator();
}
- public void Remove(Object key) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ public void Remove(Object key)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
- private sealed class NodeEnumerator : IDictionaryEnumerator {
-
- public NodeEnumerator() {
+ private sealed class NodeEnumerator : IDictionaryEnumerator
+ {
+ public NodeEnumerator()
+ {
}
// IEnumerator members
- public bool MoveNext() {
+ public bool MoveNext()
+ {
return false;
}
- public Object Current {
- get {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public Object Current
+ {
+ get
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
}
- public void Reset() {
+ public void Reset()
+ {
}
// IDictionaryEnumerator members
- public Object Key {
- get {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public Object Key
+ {
+ get
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
}
- public Object Value {
- get {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public Object Value
+ {
+ get
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
}
- public DictionaryEntry Entry {
- get {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public DictionaryEntry Entry
+ {
+ get
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
}
}
diff --git a/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs b/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs
index 298ac3e177..e313cda0fb 100644
--- a/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs
+++ b/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs
@@ -12,15 +12,16 @@
**
**
===========================================================*/
+
+using System;
+using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.Versioning;
+
namespace System.Collections.Generic
{
- using System;
- using System.Globalization;
- using System.Runtime.CompilerServices;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Runtime.Versioning;
-
#region ArraySortHelper for single arrays
internal interface IArraySortHelper<TKey>
@@ -36,8 +37,6 @@ namespace System.Collections.Generic
// Large value types may benefit from a smaller number.
internal const int IntrosortSizeThreshold = 16;
- internal const int QuickSortDepthThreshold = 32;
-
internal static int FloorLog2(int n)
{
int result = 0;
@@ -49,18 +48,18 @@ namespace System.Collections.Generic
return result;
}
- internal static void ThrowOrIgnoreBadComparer(Object comparer) {
- throw new ArgumentException(Environment.GetResourceString("Arg_BogusIComparer", comparer));
+ internal static void ThrowOrIgnoreBadComparer(Object comparer)
+ {
+ throw new ArgumentException(SR.Format(SR.Arg_BogusIComparer, comparer));
}
-
}
- [TypeDependencyAttribute("System.Collections.Generic.GenericArraySortHelper`1")]
- internal class ArraySortHelper<T>
+ [TypeDependencyAttribute("System.Collections.Generic.GenericArraySortHelper`1")]
+ internal class ArraySortHelper<T>
: IArraySortHelper<T>
{
- static volatile IArraySortHelper<T> defaultArraySortHelper;
-
+ private static volatile IArraySortHelper<T> defaultArraySortHelper;
+
public static IArraySortHelper<T> Default
{
get
@@ -71,8 +70,8 @@ namespace System.Collections.Generic
return sorter;
}
- }
-
+ }
+
private static IArraySortHelper<T> CreateArraySortHelper()
{
if (typeof(IComparable<T>).IsAssignableFrom(typeof(T)))
@@ -81,7 +80,7 @@ namespace System.Collections.Generic
}
else
{
- defaultArraySortHelper = new ArraySortHelper<T>();
+ defaultArraySortHelper = new ArraySortHelper<T>();
}
return defaultArraySortHelper;
}
@@ -91,7 +90,7 @@ namespace System.Collections.Generic
public void Sort(T[] keys, int index, int length, IComparer<T> comparer)
{
Debug.Assert(keys != null, "Check the arguments in the caller!");
- Debug.Assert( index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!");
+ Debug.Assert(index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!");
// Add a try block here to detect IComparers (or their
// underlying IComparables, etc) that are bogus.
@@ -110,7 +109,7 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -127,7 +126,7 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -150,7 +149,7 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -241,9 +240,9 @@ namespace System.Collections.Generic
}
if (partitionSize == 3)
{
- SwapIfGreater(keys, comparer, lo, hi-1);
+ SwapIfGreater(keys, comparer, lo, hi - 1);
SwapIfGreater(keys, comparer, lo, hi);
- SwapIfGreater(keys, comparer, hi-1, hi);
+ SwapIfGreater(keys, comparer, hi - 1, hi);
return;
}
@@ -375,7 +374,7 @@ namespace System.Collections.Generic
where T : IComparable<T>
{
// Do not add a constructor to this class because ArraySortHelper<T>.CreateSortHelper will not execute it
-
+
#region IArraySortHelper<T> Members
public void Sort(T[] keys, int index, int length, IComparer<T> comparer)
@@ -400,7 +399,7 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -422,7 +421,7 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -485,7 +484,7 @@ namespace System.Collections.Generic
private static void Swap(T[] a, int i, int j)
{
- if(i!=j)
+ if (i != j)
{
T t = a[i];
a[i] = a[j];
@@ -529,9 +528,9 @@ namespace System.Collections.Generic
}
if (partitionSize == 3)
{
- SwapIfGreaterWithItems(keys, lo, hi-1);
+ SwapIfGreaterWithItems(keys, lo, hi - 1);
SwapIfGreaterWithItems(keys, lo, hi);
- SwapIfGreaterWithItems(keys, hi-1, hi);
+ SwapIfGreaterWithItems(keys, hi - 1, hi);
return;
}
@@ -662,7 +661,7 @@ namespace System.Collections.Generic
}
}
-#endregion
+ #endregion
#region ArraySortHelper for paired key and value arrays
@@ -675,7 +674,7 @@ namespace System.Collections.Generic
internal class ArraySortHelper<TKey, TValue>
: IArraySortHelper<TKey, TValue>
{
- static volatile IArraySortHelper<TKey, TValue> defaultArraySortHelper;
+ private static volatile IArraySortHelper<TKey, TValue> defaultArraySortHelper;
public static IArraySortHelper<TKey, TValue> Default
{
@@ -724,7 +723,7 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -755,12 +754,12 @@ namespace System.Collections.Generic
private static void Swap(TKey[] keys, TValue[] values, int i, int j)
{
- if(i!=j)
+ if (i != j)
{
TKey k = keys[i];
keys[i] = keys[j];
keys[j] = k;
- if(values != null)
+ if (values != null)
{
TValue v = values[i];
values[i] = values[j];
@@ -810,9 +809,9 @@ namespace System.Collections.Generic
}
if (partitionSize == 3)
{
- SwapIfGreaterWithItems(keys, values, comparer, lo, hi-1);
+ SwapIfGreaterWithItems(keys, values, comparer, lo, hi - 1);
SwapIfGreaterWithItems(keys, values, comparer, lo, hi);
- SwapIfGreaterWithItems(keys, values, comparer, hi-1, hi);
+ SwapIfGreaterWithItems(keys, values, comparer, hi - 1, hi);
return;
}
@@ -913,12 +912,12 @@ namespace System.Collections.Generic
if (!(comparer.Compare(d, keys[lo + child - 1]) < 0))
break;
keys[lo + i - 1] = keys[lo + child - 1];
- if(values != null)
+ if (values != null)
values[lo + i - 1] = values[lo + child - 1];
i = child;
}
keys[lo + i - 1] = d;
- if(values != null)
+ if (values != null)
values[lo + i - 1] = dValue;
}
@@ -942,12 +941,12 @@ namespace System.Collections.Generic
while (j >= lo && comparer.Compare(t, keys[j]) < 0)
{
keys[j + 1] = keys[j];
- if(values != null)
+ if (values != null)
values[j + 1] = values[j];
j--;
}
keys[j + 1] = t;
- if(values != null)
+ if (values != null)
values[j + 1] = tValue;
}
}
@@ -960,8 +959,8 @@ namespace System.Collections.Generic
public void Sort(TKey[] keys, TValue[] values, int index, int length, IComparer<TKey> comparer)
{
Debug.Assert(keys != null, "Check the arguments in the caller!");
- Debug.Assert( index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!");
-
+ Debug.Assert(index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!");
+
// Add a try block here to detect IComparers (or their
// underlying IComparables, etc) that are bogus.
try
@@ -974,14 +973,14 @@ namespace System.Collections.Generic
{
ArraySortHelper<TKey, TValue>.IntrospectiveSort(keys, values, index, length, comparer);
}
- }
+ }
catch (IndexOutOfRangeException)
{
IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer(comparer);
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -1006,12 +1005,12 @@ namespace System.Collections.Generic
private static void Swap(TKey[] keys, TValue[] values, int i, int j)
{
- if(i != j)
+ if (i != j)
{
TKey k = keys[i];
keys[i] = keys[j];
keys[j] = k;
- if(values != null)
+ if (values != null)
{
TValue v = values[i];
values[i] = values[j];
@@ -1059,9 +1058,9 @@ namespace System.Collections.Generic
}
if (partitionSize == 3)
{
- SwapIfGreaterWithItems(keys, values, lo, hi-1);
+ SwapIfGreaterWithItems(keys, values, lo, hi - 1);
SwapIfGreaterWithItems(keys, values, lo, hi);
- SwapIfGreaterWithItems(keys, values, hi-1, hi);
+ SwapIfGreaterWithItems(keys, values, hi - 1, hi);
return;
}
@@ -1106,10 +1105,10 @@ namespace System.Collections.Generic
while (left < right)
{
- if(pivot == null)
+ if (pivot == null)
{
while (left < (hi - 1) && keys[++left] == null) ;
- while (right > lo && keys[--right] != null);
+ while (right > lo && keys[--right] != null) ;
}
else
{
@@ -1167,12 +1166,12 @@ namespace System.Collections.Generic
if (keys[lo + child - 1] == null || keys[lo + child - 1].CompareTo(d) < 0)
break;
keys[lo + i - 1] = keys[lo + child - 1];
- if(values != null)
+ if (values != null)
values[lo + i - 1] = values[lo + child - 1];
i = child;
}
keys[lo + i - 1] = d;
- if(values != null)
+ if (values != null)
values[lo + i - 1] = dValue;
}
@@ -1191,16 +1190,16 @@ namespace System.Collections.Generic
{
j = i;
t = keys[i + 1];
- tValue = (values != null)? values[i + 1] : default(TValue);
+ tValue = (values != null) ? values[i + 1] : default(TValue);
while (j >= lo && (t == null || t.CompareTo(keys[j]) < 0))
{
keys[j + 1] = keys[j];
- if(values != null)
+ if (values != null)
values[j + 1] = values[j];
j--;
}
keys[j + 1] = t;
- if(values != null)
+ if (values != null)
values[j + 1] = tValue;
}
}
diff --git a/src/mscorlib/src/System/Collections/Generic/Comparer.cs b/src/mscorlib/src/System/Collections/Generic/Comparer.cs
index 056843a606..a9b4b3f0dd 100644
--- a/src/mscorlib/src/System/Collections/Generic/Comparer.cs
+++ b/src/mscorlib/src/System/Collections/Generic/Comparer.cs
@@ -15,19 +15,14 @@ using System.Security;
using System.Runtime.Serialization;
namespace System.Collections.Generic
-{
+{
[Serializable]
- [TypeDependencyAttribute("System.Collections.Generic.ObjectComparer`1")]
+ [TypeDependencyAttribute("System.Collections.Generic.ObjectComparer`1")]
public abstract class Comparer<T> : IComparer, IComparer<T>
{
- static readonly Comparer<T> defaultComparer = CreateComparer();
-
- public static Comparer<T> Default {
- get {
- Contract.Ensures(Contract.Result<Comparer<T>>() != null);
- return defaultComparer;
- }
- }
+ // To minimize generic instantiation overhead of creating the comparer per type, we keep the generic portion of the code as small
+ // as possible and define most of the creation logic in a non-generic class.
+ public static Comparer<T> Default { get; } = (Comparer<T>)ComparerHelpers.CreateDefaultComparer(typeof(T));
public static Comparer<T> Create(Comparison<T> comparison)
{
@@ -39,69 +34,10 @@ namespace System.Collections.Generic
return new ComparisonComparer<T>(comparison);
}
- //
- // Note that logic in this method is replicated in vm\compile.cpp to ensure that NGen
- // saves the right instantiations
- //
- private static Comparer<T> CreateComparer()
- {
- object result = null;
- RuntimeType t = (RuntimeType)typeof(T);
-
- // If T implements IComparable<T> return a GenericComparer<T>
- if (typeof(IComparable<T>).IsAssignableFrom(t))
- {
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer<int>), t);
- }
- else if (default(T) == null)
- {
- // If T is a Nullable<U> where U implements IComparable<U> return a NullableComparer<U>
- if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) {
- RuntimeType u = (RuntimeType)t.GetGenericArguments()[0];
- if (typeof(IComparable<>).MakeGenericType(u).IsAssignableFrom(u)) {
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer<int>), u);
- }
- }
- }
- else if (t.IsEnum)
- {
- // Explicitly call Enum.GetUnderlyingType here. Although GetTypeCode
- // ends up doing this anyway, we end up avoiding an unnecessary P/Invoke
- // and virtual method call.
- TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(t));
-
- // Depending on the enum type, we need to special case the comparers so that we avoid boxing
- // Specialize differently for signed/unsigned types so we avoid problems with large numbers
- switch (underlyingTypeCode)
- {
- case TypeCode.SByte:
- case TypeCode.Int16:
- case TypeCode.Int32:
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(Int32EnumComparer<int>), t);
- break;
- case TypeCode.Byte:
- case TypeCode.UInt16:
- case TypeCode.UInt32:
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(UInt32EnumComparer<uint>), t);
- break;
- // 64-bit enums: use UnsafeEnumCastLong
- case TypeCode.Int64:
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(Int64EnumComparer<long>), t);
- break;
- case TypeCode.UInt64:
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(UInt64EnumComparer<ulong>), t);
- break;
- }
- }
-
- return result != null ?
- (Comparer<T>)result :
- new ObjectComparer<T>(); // Fallback to ObjectComparer, which uses boxing
- }
-
public abstract int Compare(T x, T y);
- int IComparer.Compare(object x, object y) {
+ int IComparer.Compare(object x, object y)
+ {
if (x == null) return y == null ? 0 : -1;
if (y == null) return 1;
if (x is T && y is T) return Compare((T)x, (T)y);
@@ -109,18 +45,20 @@ namespace System.Collections.Generic
return 0;
}
}
-
+
// Note: although there is a lot of shared code in the following
// comparers, we do not incorporate it into a base class for perf
// reasons. Adding another base class (even one with no fields)
// means another generic instantiation, which can be costly esp.
// for value types.
-
+
[Serializable]
internal sealed class GenericComparer<T> : Comparer<T> where T : IComparable<T>
- {
- public override int Compare(T x, T y) {
- if (x != null) {
+ {
+ public override int Compare(T x, T y)
+ {
+ if (x != null)
+ {
if (y != null) return x.CompareTo(y);
return 1;
}
@@ -139,8 +77,10 @@ namespace System.Collections.Generic
[Serializable]
internal sealed class NullableComparer<T> : Comparer<T?> where T : struct, IComparable<T>
{
- public override int Compare(T? x, T? y) {
- if (x.HasValue) {
+ public override int Compare(T? x, T? y)
+ {
+ if (x.HasValue)
+ {
if (y.HasValue) return x.value.CompareTo(y.value);
return 1;
}
@@ -159,7 +99,8 @@ namespace System.Collections.Generic
[Serializable]
internal sealed class ObjectComparer<T> : Comparer<T>
{
- public override int Compare(T x, T y) {
+ public override int Compare(T x, T y)
+ {
return System.Collections.Comparer.Default.Compare(x, y);
}
@@ -176,11 +117,13 @@ namespace System.Collections.Generic
{
private readonly Comparison<T> _comparison;
- public ComparisonComparer(Comparison<T> comparison) {
+ public ComparisonComparer(Comparison<T> comparison)
+ {
_comparison = comparison;
}
- public override int Compare(T x, T y) {
+ public override int Compare(T x, T y)
+ {
return _comparison(x, y);
}
}
@@ -196,12 +139,12 @@ namespace System.Collections.Generic
{
public Int32EnumComparer()
{
- Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
+ Debug.Assert(typeof(T).IsEnum);
}
-
+
// Used by the serialization engine.
private Int32EnumComparer(SerializationInfo info, StreamingContext context) { }
-
+
public override int Compare(T x, T y)
{
int ix = JitHelpers.UnsafeEnumCast(x);
@@ -231,12 +174,12 @@ namespace System.Collections.Generic
{
public UInt32EnumComparer()
{
- Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
+ Debug.Assert(typeof(T).IsEnum);
}
-
+
// Used by the serialization engine.
private UInt32EnumComparer(SerializationInfo info, StreamingContext context) { }
-
+
public override int Compare(T x, T y)
{
uint ix = (uint)JitHelpers.UnsafeEnumCast(x);
@@ -262,9 +205,9 @@ namespace System.Collections.Generic
{
public Int64EnumComparer()
{
- Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
+ Debug.Assert(typeof(T).IsEnum);
}
-
+
public override int Compare(T x, T y)
{
long lx = JitHelpers.UnsafeEnumCastLong(x);
@@ -290,12 +233,12 @@ namespace System.Collections.Generic
{
public UInt64EnumComparer()
{
- Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
+ Debug.Assert(typeof(T).IsEnum);
}
-
+
// Used by the serialization engine.
private UInt64EnumComparer(SerializationInfo info, StreamingContext context) { }
-
+
public override int Compare(T x, T y)
{
ulong lx = (ulong)JitHelpers.UnsafeEnumCastLong(x);
diff --git a/src/mscorlib/src/System/Collections/Generic/ComparerHelpers.cs b/src/mscorlib/src/System/Collections/Generic/ComparerHelpers.cs
new file mode 100644
index 0000000000..3e428413d4
--- /dev/null
+++ b/src/mscorlib/src/System/Collections/Generic/ComparerHelpers.cs
@@ -0,0 +1,210 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// 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.Diagnostics;
+using static System.RuntimeTypeHandle;
+
+namespace System.Collections.Generic
+{
+ /// <summary>
+ /// Helper class for creating the default <see cref="Comparer{T}"/> and <see cref="EqualityComparer{T}"/>.
+ /// </summary>
+ /// <remarks>
+ /// This class is intentionally type-unsafe and non-generic to minimize the generic instantiation overhead of creating
+ /// the default comparer/equality comparer for a new type parameter. Efficiency of the methods in here does not matter too
+ /// much since they will only be run once per type parameter, but generic code involved in creating the comparers needs to be
+ /// kept to a minimum.
+ /// </remarks>
+ internal static class ComparerHelpers
+ {
+ /// <summary>
+ /// Creates the default <see cref="Comparer{T}"/>.
+ /// </summary>
+ /// <param name="type">The type to create the default comparer for.</param>
+ /// <remarks>
+ /// The logic in this method is replicated in vm/compile.cpp to ensure that NGen saves the right instantiations.
+ /// </remarks>
+ internal static object CreateDefaultComparer(Type type)
+ {
+ Debug.Assert(type != null && type is RuntimeType);
+
+ object result = null;
+ var runtimeType = (RuntimeType)type;
+
+ // If T implements IComparable<T> return a GenericComparer<T>
+ if (typeof(IComparable<>).MakeGenericType(type).IsAssignableFrom(type))
+ {
+ result = CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer<int>), runtimeType);
+ }
+ // Nullable does not implement IComparable<T?> directly because that would add an extra interface call per comparison.
+ // Instead, it relies on Comparer<T?>.Default to specialize for nullables and do the lifted comparisons if T implements IComparable.
+ else if (type.IsGenericType)
+ {
+ if (type.GetGenericTypeDefinition() == typeof(Nullable<>))
+ {
+ result = TryCreateNullableComparer(runtimeType);
+ }
+ }
+ // The comparer for enums is specialized to avoid boxing.
+ else if (type.IsEnum)
+ {
+ result = TryCreateEnumComparer(runtimeType);
+ }
+
+ return result ?? CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ObjectComparer<object>), runtimeType);
+ }
+
+ /// <summary>
+ /// Creates the default <see cref="Comparer{T}"/> for a nullable type.
+ /// </summary>
+ /// <param name="nullableType">The nullable type to create the default comparer for.</param>
+ private static object TryCreateNullableComparer(RuntimeType nullableType)
+ {
+ Debug.Assert(nullableType != null);
+ Debug.Assert(nullableType.IsGenericType && nullableType.GetGenericTypeDefinition() == typeof(Nullable<>));
+
+ var embeddedType = (RuntimeType)nullableType.GetGenericArguments()[0];
+
+ if (typeof(IComparable<>).MakeGenericType(embeddedType).IsAssignableFrom(embeddedType))
+ {
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer<int>), embeddedType);
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Creates the default <see cref="Comparer{T}"/> for an enum type.
+ /// </summary>
+ /// <param name="enumType">The enum type to create the default comparer for.</param>
+ private static object TryCreateEnumComparer(RuntimeType enumType)
+ {
+ Debug.Assert(enumType != null);
+ Debug.Assert(enumType.IsEnum);
+
+ // Explicitly call Enum.GetUnderlyingType here. Although GetTypeCode
+ // ends up doing this anyway, we end up avoiding an unnecessary P/Invoke
+ // and virtual method call.
+ TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(enumType));
+
+ // Depending on the enum type, we need to special case the comparers so that we avoid boxing.
+ // Specialize differently for signed/unsigned types so we avoid problems with large numbers.
+ switch (underlyingTypeCode)
+ {
+ case TypeCode.SByte:
+ case TypeCode.Int16:
+ case TypeCode.Int32:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(Int32EnumComparer<int>), enumType);
+ case TypeCode.Byte:
+ case TypeCode.UInt16:
+ case TypeCode.UInt32:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(UInt32EnumComparer<uint>), enumType);
+ // 64-bit enums: Use `UnsafeEnumCastLong`
+ case TypeCode.Int64:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(Int64EnumComparer<long>), enumType);
+ case TypeCode.UInt64:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(UInt64EnumComparer<ulong>), enumType);
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Creates the default <see cref="EqualityComparer{T}"/>.
+ /// </summary>
+ /// <param name="type">The type to create the default equality comparer for.</param>
+ /// <remarks>
+ /// The logic in this method is replicated in vm/compile.cpp to ensure that NGen saves the right instantiations.
+ /// </remarks>
+ internal static object CreateDefaultEqualityComparer(Type type)
+ {
+ Debug.Assert(type != null && type is RuntimeType);
+
+ object result = null;
+ var runtimeType = (RuntimeType)type;
+
+ // Specialize for byte so Array.IndexOf is faster.
+ if (type == typeof(byte))
+ {
+ result = new ByteEqualityComparer();
+ }
+ // If T implements IEquatable<T> return a GenericEqualityComparer<T>
+ else if (typeof(IEquatable<>).MakeGenericType(type).IsAssignableFrom(type))
+ {
+ result = CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer<int>), runtimeType);
+ }
+ // Nullable does not implement IEquatable<T?> directly because that would add an extra interface call per comparison.
+ // Instead, it relies on EqualityComparer<T?>.Default to specialize for nullables and do the lifted comparisons if T implements IEquatable.
+ else if (type.IsGenericType)
+ {
+ if (type.GetGenericTypeDefinition() == typeof(Nullable<>))
+ {
+ result = TryCreateNullableEqualityComparer(runtimeType);
+ }
+ }
+ // The equality comparer for enums is specialized to avoid boxing.
+ else if (type.IsEnum)
+ {
+ result = TryCreateEnumEqualityComparer(runtimeType);
+ }
+
+ return result ?? CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ObjectEqualityComparer<object>), runtimeType);
+ }
+
+ /// <summary>
+ /// Creates the default <see cref="EqualityComparer{T}"/> for a nullable type.
+ /// </summary>
+ /// <param name="nullableType">The nullable type to create the default equality comparer for.</param>
+ private static object TryCreateNullableEqualityComparer(RuntimeType nullableType)
+ {
+ Debug.Assert(nullableType != null);
+ Debug.Assert(nullableType.IsGenericType && nullableType.GetGenericTypeDefinition() == typeof(Nullable<>));
+
+ var embeddedType = (RuntimeType)nullableType.GetGenericArguments()[0];
+
+ if (typeof(IEquatable<>).MakeGenericType(embeddedType).IsAssignableFrom(embeddedType))
+ {
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableEqualityComparer<int>), embeddedType);
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Creates the default <see cref="EqualityComparer{T}"/> for an enum type.
+ /// </summary>
+ /// <param name="enumType">The enum type to create the default equality comparer for.</param>
+ private static object TryCreateEnumEqualityComparer(RuntimeType enumType)
+ {
+ Debug.Assert(enumType != null);
+ Debug.Assert(enumType.IsEnum);
+
+ // See the METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST and METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST_LONG cases in getILIntrinsicImplementation
+ // for how we cast the enum types to integral values in the comparer without boxing.
+
+ TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(enumType));
+
+ // Depending on the enum type, we need to special case the comparers so that we avoid boxing.
+ // Note: We have different comparers for short and sbyte, since for those types GetHashCode does not simply return the value.
+ // We need to preserve what they would return.
+ switch (underlyingTypeCode)
+ {
+ case TypeCode.Int16:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ShortEnumEqualityComparer<short>), enumType);
+ case TypeCode.SByte:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(SByteEnumEqualityComparer<sbyte>), enumType);
+ case TypeCode.Int32:
+ case TypeCode.UInt32:
+ case TypeCode.Byte:
+ case TypeCode.UInt16:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer<int>), enumType);
+ case TypeCode.Int64:
+ case TypeCode.UInt64:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(LongEnumEqualityComparer<long>), enumType);
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Collections/Generic/DebugView.cs b/src/mscorlib/src/System/Collections/Generic/DebugView.cs
index 27c5011147..dc487c1411 100644
--- a/src/mscorlib/src/System/Collections/Generic/DebugView.cs
+++ b/src/mscorlib/src/System/Collections/Generic/DebugView.cs
@@ -13,116 +13,112 @@
**
=============================================================================*/
-namespace System.Collections.Generic {
- using System;
- using System.Collections.ObjectModel;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
+using System;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+namespace System.Collections.Generic
+{
//
// VS IDE can't differentiate between types with the same name from different
// assembly. So we need to use different names for collection debug view for
// collections in mscorlib.dll and system.dll.
//
- internal sealed class Mscorlib_CollectionDebugView<T> {
- private ICollection<T> collection;
-
- public Mscorlib_CollectionDebugView(ICollection<T> collection) {
+ internal sealed class Mscorlib_CollectionDebugView<T>
+ {
+ private ICollection<T> collection;
+
+ public Mscorlib_CollectionDebugView(ICollection<T> collection)
+ {
if (collection == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
- this.collection = collection;
+ this.collection = collection;
}
-
+
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
- public T[] Items {
- get {
+ public T[] Items
+ {
+ get
+ {
T[] items = new T[collection.Count];
collection.CopyTo(items, 0);
return items;
}
}
- }
+ }
- internal sealed class Mscorlib_DictionaryKeyCollectionDebugView<TKey, TValue> {
- private ICollection<TKey> collection;
-
- public Mscorlib_DictionaryKeyCollectionDebugView(ICollection<TKey> collection) {
+ internal sealed class Mscorlib_DictionaryKeyCollectionDebugView<TKey, TValue>
+ {
+ private ICollection<TKey> collection;
+
+ public Mscorlib_DictionaryKeyCollectionDebugView(ICollection<TKey> collection)
+ {
if (collection == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
- this.collection = collection;
+ this.collection = collection;
}
-
+
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
- public TKey[] Items {
- get {
+ public TKey[] Items
+ {
+ get
+ {
TKey[] items = new TKey[collection.Count];
collection.CopyTo(items, 0);
return items;
}
}
- }
+ }
- internal sealed class Mscorlib_DictionaryValueCollectionDebugView<TKey, TValue> {
- private ICollection<TValue> collection;
-
- public Mscorlib_DictionaryValueCollectionDebugView(ICollection<TValue> collection) {
+ internal sealed class Mscorlib_DictionaryValueCollectionDebugView<TKey, TValue>
+ {
+ private ICollection<TValue> collection;
+
+ public Mscorlib_DictionaryValueCollectionDebugView(ICollection<TValue> collection)
+ {
if (collection == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
- this.collection = collection;
+ this.collection = collection;
}
-
+
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
- public TValue[] Items {
- get {
+ public TValue[] Items
+ {
+ get
+ {
TValue[] items = new TValue[collection.Count];
collection.CopyTo(items, 0);
return items;
}
}
- }
+ }
+
+ internal sealed class Mscorlib_DictionaryDebugView<K, V>
+ {
+ private IDictionary<K, V> dict;
- internal sealed class Mscorlib_DictionaryDebugView<K, V> {
- private IDictionary<K, V> dict;
-
- public Mscorlib_DictionaryDebugView(IDictionary<K, V> dictionary) {
+ public Mscorlib_DictionaryDebugView(IDictionary<K, V> dictionary)
+ {
if (dictionary == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
- this.dict = dictionary;
+ dict = dictionary;
}
-
+
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
- public KeyValuePair<K, V>[] Items {
- get {
+ public KeyValuePair<K, V>[] Items
+ {
+ get
+ {
KeyValuePair<K, V>[] items = new KeyValuePair<K, V>[dict.Count];
dict.CopyTo(items, 0);
return items;
}
}
- }
-
- internal sealed class Mscorlib_KeyedCollectionDebugView<K, T> {
- private KeyedCollection<K, T> kc;
-
- public Mscorlib_KeyedCollectionDebugView(KeyedCollection<K, T> keyedCollection) {
- if (keyedCollection == null) {
- throw new ArgumentNullException(nameof(keyedCollection));
- }
- Contract.EndContractBlock();
+ }
- kc = keyedCollection;
- }
-
- [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
- public T[] Items {
- get {
- T[] items = new T[kc.Count];
- kc.CopyTo(items, 0);
- return items;
- }
- }
- }
}
diff --git a/src/mscorlib/src/System/Collections/Generic/Dictionary.cs b/src/mscorlib/src/System/Collections/Generic/Dictionary.cs
index 7b60e31031..409b23b541 100644
--- a/src/mscorlib/src/System/Collections/Generic/Dictionary.cs
+++ b/src/mscorlib/src/System/Collections/Generic/Dictionary.cs
@@ -41,20 +41,43 @@
** to serialization such that this code doesn't need to build in
** silverlight.
===========================================================*/
-namespace System.Collections.Generic {
+namespace System.Collections.Generic
+{
using System;
using System.Collections;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.Serialization;
+ /// <summary>
+ /// Used internally to control behavior of insertion into a <see cref="Dictionary{TKey, TValue}"/>.
+ /// </summary>
+ internal enum InsertionBehavior : byte
+ {
+ /// <summary>
+ /// The default insertion behavior.
+ /// </summary>
+ None = 0,
+
+ /// <summary>
+ /// Specifies that an existing entry with the same key should be overwritten if encountered.
+ /// </summary>
+ OverwriteExisting = 1,
+
+ /// <summary>
+ /// Specifies that if an existing entry with the same key is encountered, an exception should be thrown.
+ /// </summary>
+ ThrowOnExisting = 2
+ }
+
[DebuggerTypeProxy(typeof(Mscorlib_DictionaryDebugView<,>))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
- public class Dictionary<TKey,TValue>: IDictionary<TKey,TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue>, ISerializable, IDeserializationCallback {
-
- private struct Entry {
+ public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue>, ISerializable, IDeserializationCallback
+ {
+ private struct Entry
+ {
public int hashCode; // Lower 31 bits of hash code, -1 if unused
public int next; // Index of next entry, -1 if last
public TKey key; // Key of entry
@@ -71,38 +94,40 @@ namespace System.Collections.Generic {
private KeyCollection keys;
private ValueCollection values;
private Object _syncRoot;
-
+
// constants for serialization
private const String VersionName = "Version";
private const String HashSizeName = "HashSize"; // Must save buckets.Length
private const String KeyValuePairsName = "KeyValuePairs";
private const String ComparerName = "Comparer";
- public Dictionary(): this(0, null) {}
+ public Dictionary() : this(0, null) { }
- public Dictionary(int capacity): this(capacity, null) {}
+ public Dictionary(int capacity) : this(capacity, null) { }
- public Dictionary(IEqualityComparer<TKey> comparer): this(0, comparer) {}
+ public Dictionary(IEqualityComparer<TKey> comparer) : this(0, comparer) { }
- public Dictionary(int capacity, IEqualityComparer<TKey> comparer) {
+ public Dictionary(int capacity, IEqualityComparer<TKey> comparer)
+ {
if (capacity < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity);
if (capacity > 0) Initialize(capacity);
this.comparer = comparer ?? EqualityComparer<TKey>.Default;
#if FEATURE_RANDOMIZED_STRING_HASHING
- if (HashHelpers.s_UseRandomizedStringHashing && comparer == EqualityComparer<string>.Default)
+ if (HashHelpers.s_UseRandomizedStringHashing && this.comparer == EqualityComparer<string>.Default)
{
- this.comparer = (IEqualityComparer<TKey>) NonRandomizedStringEqualityComparer.Default;
+ this.comparer = (IEqualityComparer<TKey>)NonRandomizedStringEqualityComparer.Default;
}
#endif // FEATURE_RANDOMIZED_STRING_HASHING
}
- public Dictionary(IDictionary<TKey,TValue> dictionary): this(dictionary, null) {}
-
- public Dictionary(IDictionary<TKey,TValue> dictionary, IEqualityComparer<TKey> comparer):
- this(dictionary != null? dictionary.Count: 0, comparer) {
+ public Dictionary(IDictionary<TKey, TValue> dictionary) : this(dictionary, null) { }
- if( dictionary == null) {
+ public Dictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) :
+ this(dictionary != null ? dictionary.Count : 0, comparer)
+ {
+ if (dictionary == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
}
@@ -110,138 +135,174 @@ namespace System.Collections.Generic {
// avoid the enumerator allocation and overhead by looping through the entries array directly.
// We only do this when dictionary is Dictionary<TKey,TValue> and not a subclass, to maintain
// back-compat with subclasses that may have overridden the enumerator behavior.
- if (dictionary.GetType() == typeof(Dictionary<TKey,TValue>)) {
- Dictionary<TKey,TValue> d = (Dictionary<TKey,TValue>)dictionary;
+ if (dictionary.GetType() == typeof(Dictionary<TKey, TValue>))
+ {
+ Dictionary<TKey, TValue> d = (Dictionary<TKey, TValue>)dictionary;
int count = d.count;
Entry[] entries = d.entries;
- for (int i = 0; i < count; i++) {
- if (entries[i].hashCode >= 0) {
+ for (int i = 0; i < count; i++)
+ {
+ if (entries[i].hashCode >= 0)
+ {
Add(entries[i].key, entries[i].value);
}
}
return;
}
- foreach (KeyValuePair<TKey,TValue> pair in dictionary) {
+ foreach (KeyValuePair<TKey, TValue> pair in dictionary)
+ {
Add(pair.Key, pair.Value);
}
}
- public Dictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection):
- this(collection, null) { }
+ public Dictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection) :
+ this(collection, null)
+ { }
- public Dictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer):
+ public Dictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer) :
this((collection as ICollection<KeyValuePair<TKey, TValue>>)?.Count ?? 0, comparer)
{
- if (collection == null) {
+ if (collection == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
- foreach (KeyValuePair<TKey, TValue> pair in collection) {
+ foreach (KeyValuePair<TKey, TValue> pair in collection)
+ {
Add(pair.Key, pair.Value);
}
}
- protected Dictionary(SerializationInfo info, StreamingContext context) {
+ protected Dictionary(SerializationInfo info, StreamingContext context)
+ {
//We can't do anything with the keys and values until the entire graph has been deserialized
//and we have a resonable estimate that GetHashCode is not going to fail. For the time being,
//we'll just cache this. The graph is not valid until OnDeserialization has been called.
HashHelpers.SerializationInfoTable.Add(this, info);
}
-
- public IEqualityComparer<TKey> Comparer {
- get {
- return comparer;
- }
+
+ public IEqualityComparer<TKey> Comparer
+ {
+ get
+ {
+ return comparer;
+ }
}
-
- public int Count {
+
+ public int Count
+ {
get { return count - freeCount; }
}
- public KeyCollection Keys {
- get {
+ public KeyCollection Keys
+ {
+ get
+ {
Contract.Ensures(Contract.Result<KeyCollection>() != null);
if (keys == null) keys = new KeyCollection(this);
return keys;
}
}
- ICollection<TKey> IDictionary<TKey, TValue>.Keys {
- get {
- if (keys == null) keys = new KeyCollection(this);
+ ICollection<TKey> IDictionary<TKey, TValue>.Keys
+ {
+ get
+ {
+ if (keys == null) keys = new KeyCollection(this);
return keys;
}
}
- IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys {
- get {
- if (keys == null) keys = new KeyCollection(this);
+ IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys
+ {
+ get
+ {
+ if (keys == null) keys = new KeyCollection(this);
return keys;
}
}
- public ValueCollection Values {
- get {
+ public ValueCollection Values
+ {
+ get
+ {
Contract.Ensures(Contract.Result<ValueCollection>() != null);
if (values == null) values = new ValueCollection(this);
return values;
}
}
- ICollection<TValue> IDictionary<TKey, TValue>.Values {
- get {
+ ICollection<TValue> IDictionary<TKey, TValue>.Values
+ {
+ get
+ {
if (values == null) values = new ValueCollection(this);
return values;
}
}
- IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values {
- get {
+ IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values
+ {
+ get
+ {
if (values == null) values = new ValueCollection(this);
return values;
}
}
- public TValue this[TKey key] {
- get {
+ public TValue this[TKey key]
+ {
+ get
+ {
int i = FindEntry(key);
if (i >= 0) return entries[i].value;
ThrowHelper.ThrowKeyNotFoundException();
return default(TValue);
}
- set {
- Insert(key, value, false);
+ set
+ {
+ bool modified = TryInsert(key, value, InsertionBehavior.OverwriteExisting);
+ Debug.Assert(modified);
}
}
- public void Add(TKey key, TValue value) {
- Insert(key, value, true);
+ public void Add(TKey key, TValue value)
+ {
+ bool modified = TryInsert(key, value, InsertionBehavior.ThrowOnExisting);
+ Debug.Assert(modified); // If there was an existing key and the Add failed, an exception will already have been thrown.
}
- void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> keyValuePair) {
+ void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> keyValuePair)
+ {
Add(keyValuePair.Key, keyValuePair.Value);
}
- bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> keyValuePair) {
+ bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> keyValuePair)
+ {
int i = FindEntry(keyValuePair.Key);
- if( i >= 0 && EqualityComparer<TValue>.Default.Equals(entries[i].value, keyValuePair.Value)) {
+ if (i >= 0 && EqualityComparer<TValue>.Default.Equals(entries[i].value, keyValuePair.Value))
+ {
return true;
}
return false;
}
- bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> keyValuePair) {
+ bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> keyValuePair)
+ {
int i = FindEntry(keyValuePair.Key);
- if( i >= 0 && EqualityComparer<TValue>.Default.Equals(entries[i].value, keyValuePair.Value)) {
+ if (i >= 0 && EqualityComparer<TValue>.Default.Equals(entries[i].value, keyValuePair.Value))
+ {
Remove(keyValuePair.Key);
return true;
}
return false;
}
- public void Clear() {
- if (count > 0) {
+ public void Clear()
+ {
+ if (count > 0)
+ {
for (int i = 0; i < buckets.Length; i++) buckets[i] = -1;
Array.Clear(entries, 0, count);
freeList = -1;
@@ -251,90 +312,106 @@ namespace System.Collections.Generic {
}
}
- public bool ContainsKey(TKey key) {
+ public bool ContainsKey(TKey key)
+ {
return FindEntry(key) >= 0;
}
- public bool ContainsValue(TValue value) {
- if (value == null) {
- for (int i = 0; i < count; i++) {
+ public bool ContainsValue(TValue value)
+ {
+ if (value == null)
+ {
+ for (int i = 0; i < count; i++)
+ {
if (entries[i].hashCode >= 0 && entries[i].value == null) return true;
}
}
- else {
+ else
+ {
EqualityComparer<TValue> c = EqualityComparer<TValue>.Default;
- for (int i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++)
+ {
if (entries[i].hashCode >= 0 && c.Equals(entries[i].value, value)) return true;
}
}
return false;
}
- private void CopyTo(KeyValuePair<TKey,TValue>[] array, int index) {
- if (array == null) {
+ private void CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
-
- if (index < 0 || index > array.Length ) {
+
+ if (index < 0 || index > array.Length)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < Count) {
+ if (array.Length - index < Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
int count = this.count;
Entry[] entries = this.entries;
- for (int i = 0; i < count; i++) {
- if (entries[i].hashCode >= 0) {
- array[index++] = new KeyValuePair<TKey,TValue>(entries[i].key, entries[i].value);
+ for (int i = 0; i < count; i++)
+ {
+ if (entries[i].hashCode >= 0)
+ {
+ array[index++] = new KeyValuePair<TKey, TValue>(entries[i].key, entries[i].value);
}
}
}
- public Enumerator GetEnumerator() {
+ public Enumerator GetEnumerator()
+ {
return new Enumerator(this, Enumerator.KeyValuePair);
}
- IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator() {
+ IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
+ {
return new Enumerator(this, Enumerator.KeyValuePair);
- }
+ }
- public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+ public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.info);
}
info.AddValue(VersionName, version);
-
-#if FEATURE_RANDOMIZED_STRING_HASHING
- info.AddValue(ComparerName, HashHelpers.GetEqualityComparerForSerialization(comparer), typeof(IEqualityComparer<TKey>));
-#else
info.AddValue(ComparerName, comparer, typeof(IEqualityComparer<TKey>));
-#endif
-
info.AddValue(HashSizeName, buckets == null ? 0 : buckets.Length); //This is the length of the bucket array.
- if( buckets != null) {
+ if (buckets != null)
+ {
KeyValuePair<TKey, TValue>[] array = new KeyValuePair<TKey, TValue>[Count];
CopyTo(array, 0);
info.AddValue(KeyValuePairsName, array, typeof(KeyValuePair<TKey, TValue>[]));
}
}
- private int FindEntry(TKey key) {
- if( key == null) {
+ private int FindEntry(TKey key)
+ {
+ if (key == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
- if (buckets != null) {
+ if (buckets != null)
+ {
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
- for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entries[i].next) {
+ for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entries[i].next)
+ {
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) return i;
}
}
return -1;
}
- private void Initialize(int capacity) {
+ private void Initialize(int capacity)
+ {
int size = HashHelpers.GetPrime(capacity);
buckets = new int[size];
for (int i = 0; i < buckets.Length; i++) buckets[i] = -1;
@@ -342,9 +419,10 @@ namespace System.Collections.Generic {
freeList = -1;
}
- private void Insert(TKey key, TValue value, bool add) {
-
- if( key == null ) {
+ private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)
+ {
+ if (key == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
@@ -356,27 +434,38 @@ namespace System.Collections.Generic {
int collisionCount = 0;
#endif
- for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next) {
- if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) {
- if (add) {
+ for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next)
+ {
+ if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
+ {
+ if (behavior == InsertionBehavior.OverwriteExisting)
+ {
+ entries[i].value = value;
+ version++;
+ return true;
+ }
+
+ if (behavior == InsertionBehavior.ThrowOnExisting)
+ {
ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(key);
}
- entries[i].value = value;
- version++;
- return;
- }
+
+ return false;
+ }
#if FEATURE_RANDOMIZED_STRING_HASHING
collisionCount++;
#endif
}
int index;
- if (freeCount > 0) {
+ if (freeCount > 0)
+ {
index = freeList;
freeList = entries[index].next;
freeCount--;
}
- else {
+ else
+ {
if (count == entries.Length)
{
Resize();
@@ -399,52 +488,60 @@ namespace System.Collections.Generic {
// Note, randomized string hashing is turned on by default on coreclr so EqualityComparer<string>.Default will
// be using randomized string hashing
- if (collisionCount > HashHelpers.HashCollisionThreshold && comparer == NonRandomizedStringEqualityComparer.Default)
+ if (collisionCount > HashHelpers.HashCollisionThreshold && comparer == NonRandomizedStringEqualityComparer.Default)
{
- comparer = (IEqualityComparer<TKey>) EqualityComparer<string>.Default;
+ comparer = (IEqualityComparer<TKey>)EqualityComparer<string>.Default;
Resize(entries.Length, true);
}
#endif
+ return true;
}
- public virtual void OnDeserialization(Object sender) {
+ public virtual void OnDeserialization(Object sender)
+ {
SerializationInfo siInfo;
HashHelpers.SerializationInfoTable.TryGetValue(this, out siInfo);
-
- if (siInfo==null) {
+
+ if (siInfo == null)
+ {
// It might be necessary to call OnDeserialization from a container if the container object also implements
// OnDeserialization. However, remoting will call OnDeserialization again.
// We can return immediately if this function is called twice.
// Note we set remove the serialization info from the table at the end of this method.
return;
- }
-
+ }
+
int realVersion = siInfo.GetInt32(VersionName);
int hashsize = siInfo.GetInt32(HashSizeName);
- comparer = (IEqualityComparer<TKey>)siInfo.GetValue(ComparerName, typeof(IEqualityComparer<TKey>));
-
- if( hashsize != 0) {
+ comparer = (IEqualityComparer<TKey>)siInfo.GetValue(ComparerName, typeof(IEqualityComparer<TKey>));
+
+ if (hashsize != 0)
+ {
buckets = new int[hashsize];
for (int i = 0; i < buckets.Length; i++) buckets[i] = -1;
entries = new Entry[hashsize];
freeList = -1;
- KeyValuePair<TKey, TValue>[] array = (KeyValuePair<TKey, TValue>[])
+ KeyValuePair<TKey, TValue>[] array = (KeyValuePair<TKey, TValue>[])
siInfo.GetValue(KeyValuePairsName, typeof(KeyValuePair<TKey, TValue>[]));
- if (array==null) {
+ if (array == null)
+ {
ThrowHelper.ThrowSerializationException(ExceptionResource.Serialization_MissingKeys);
}
- for (int i=0; i<array.Length; i++) {
- if ( array[i].Key == null) {
+ for (int i = 0; i < array.Length; i++)
+ {
+ if (array[i].Key == null)
+ {
ThrowHelper.ThrowSerializationException(ExceptionResource.Serialization_NullKey);
}
- Insert(array[i].Key, array[i].Value, true);
+ Add(array[i].Key, array[i].Value);
}
}
- else {
+ else
+ {
buckets = null;
}
@@ -452,25 +549,32 @@ namespace System.Collections.Generic {
HashHelpers.SerializationInfoTable.Remove(this);
}
- private void Resize() {
+ private void Resize()
+ {
Resize(HashHelpers.ExpandPrime(count), false);
}
- private void Resize(int newSize, bool forceNewHashCodes) {
+ private void Resize(int newSize, bool forceNewHashCodes)
+ {
Debug.Assert(newSize >= entries.Length);
int[] newBuckets = new int[newSize];
for (int i = 0; i < newBuckets.Length; i++) newBuckets[i] = -1;
Entry[] newEntries = new Entry[newSize];
Array.Copy(entries, 0, newEntries, 0, count);
- if(forceNewHashCodes) {
- for (int i = 0; i < count; i++) {
- if(newEntries[i].hashCode != -1) {
+ if (forceNewHashCodes)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ if (newEntries[i].hashCode != -1)
+ {
newEntries[i].hashCode = (comparer.GetHashCode(newEntries[i].key) & 0x7FFFFFFF);
}
}
}
- for (int i = 0; i < count; i++) {
- if (newEntries[i].hashCode >= 0) {
+ for (int i = 0; i < count; i++)
+ {
+ if (newEntries[i].hashCode >= 0)
+ {
int bucket = newEntries[i].hashCode % newSize;
newEntries[i].next = newBuckets[bucket];
newBuckets[bucket] = i;
@@ -480,21 +584,31 @@ namespace System.Collections.Generic {
entries = newEntries;
}
- public bool Remove(TKey key) {
- if(key == null) {
+ // The overload Remove(TKey key, out TValue value) is a copy of this method with one additional
+ // statement to copy the value for entry being removed into the output parameter.
+ // Code has been intentionally duplicated for performance reasons.
+ public bool Remove(TKey key)
+ {
+ if (key == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
- if (buckets != null) {
+ if (buckets != null)
+ {
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int bucket = hashCode % buckets.Length;
int last = -1;
- for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next) {
- if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) {
- if (last < 0) {
+ for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next)
+ {
+ if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
+ {
+ if (last < 0)
+ {
buckets[bucket] = entries[i].next;
}
- else {
+ else
+ {
entries[last].next = entries[i].next;
}
entries[i].hashCode = -1;
@@ -511,9 +625,56 @@ namespace System.Collections.Generic {
return false;
}
- public bool TryGetValue(TKey key, out TValue value) {
+ // This overload is a copy of the overload Remove(TKey key) with one additional
+ // statement to copy the value for entry being removed into the output parameter.
+ // Code has been intentionally duplicated for performance reasons.
+ public bool Remove(TKey key, out TValue value)
+ {
+ if (key == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ }
+
+ if (buckets != null)
+ {
+ int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
+ int bucket = hashCode % buckets.Length;
+ int last = -1;
+ for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next)
+ {
+ if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
+ {
+ if (last < 0)
+ {
+ buckets[bucket] = entries[i].next;
+ }
+ else
+ {
+ entries[last].next = entries[i].next;
+ }
+
+ value = entries[i].value;
+
+ entries[i].hashCode = -1;
+ entries[i].next = freeList;
+ entries[i].key = default(TKey);
+ entries[i].value = default(TValue);
+ freeList = i;
+ freeCount++;
+ version++;
+ return true;
+ }
+ }
+ }
+ value = default(TValue);
+ return false;
+ }
+
+ public bool TryGetValue(TKey key, out TValue value)
+ {
int i = FindEntry(key);
- if (i >= 0) {
+ if (i >= 0)
+ {
value = entries[i].value;
return true;
}
@@ -536,195 +697,246 @@ namespace System.Collections.Generic {
return defaultValue;
}
- bool ICollection<KeyValuePair<TKey,TValue>>.IsReadOnly {
+ public bool TryAdd(TKey key, TValue value) => TryInsert(key, value, InsertionBehavior.None);
+
+ bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
+ {
get { return false; }
}
- void ICollection<KeyValuePair<TKey,TValue>>.CopyTo(KeyValuePair<TKey,TValue>[] array, int index) {
+ void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
+ {
CopyTo(array, index);
}
- void ICollection.CopyTo(Array array, int index) {
- if (array == null) {
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
-
- if (array.Rank != 1) {
+
+ if (array.Rank != 1)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if( array.GetLowerBound(0) != 0 ) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
-
- if (index < 0 || index > array.Length) {
+
+ if (index < 0 || index > array.Length)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < Count) {
+ if (array.Length - index < Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
-
- KeyValuePair<TKey,TValue>[] pairs = array as KeyValuePair<TKey,TValue>[];
- if (pairs != null) {
+
+ KeyValuePair<TKey, TValue>[] pairs = array as KeyValuePair<TKey, TValue>[];
+ if (pairs != null)
+ {
CopyTo(pairs, index);
}
- else if( array is DictionaryEntry[]) {
+ else if (array is DictionaryEntry[])
+ {
DictionaryEntry[] dictEntryArray = array as DictionaryEntry[];
Entry[] entries = this.entries;
- for (int i = 0; i < count; i++) {
- if (entries[i].hashCode >= 0) {
+ for (int i = 0; i < count; i++)
+ {
+ if (entries[i].hashCode >= 0)
+ {
dictEntryArray[index++] = new DictionaryEntry(entries[i].key, entries[i].value);
}
- }
+ }
}
- else {
+ else
+ {
object[] objects = array as object[];
- if (objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
- try {
+ try
+ {
int count = this.count;
Entry[] entries = this.entries;
- for (int i = 0; i < count; i++) {
- if (entries[i].hashCode >= 0) {
- objects[index++] = new KeyValuePair<TKey,TValue>(entries[i].key, entries[i].value);
+ for (int i = 0; i < count; i++)
+ {
+ if (entries[i].hashCode >= 0)
+ {
+ objects[index++] = new KeyValuePair<TKey, TValue>(entries[i].key, entries[i].value);
}
}
}
- catch(ArrayTypeMismatchException) {
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
- IEnumerator IEnumerable.GetEnumerator() {
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return new Enumerator(this, Enumerator.KeyValuePair);
}
-
- bool ICollection.IsSynchronized {
+
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- object ICollection.SyncRoot {
- get {
- if( _syncRoot == null) {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
- return _syncRoot;
+ return _syncRoot;
}
}
- bool IDictionary.IsFixedSize {
+ bool IDictionary.IsFixedSize
+ {
get { return false; }
}
- bool IDictionary.IsReadOnly {
+ bool IDictionary.IsReadOnly
+ {
get { return false; }
}
- ICollection IDictionary.Keys {
+ ICollection IDictionary.Keys
+ {
get { return (ICollection)Keys; }
}
-
- ICollection IDictionary.Values {
+
+ ICollection IDictionary.Values
+ {
get { return (ICollection)Values; }
}
-
- object IDictionary.this[object key] {
- get {
- if( IsCompatibleKey(key)) {
+
+ object IDictionary.this[object key]
+ {
+ get
+ {
+ if (IsCompatibleKey(key))
+ {
int i = FindEntry((TKey)key);
- if (i >= 0) {
- return entries[i].value;
+ if (i >= 0)
+ {
+ return entries[i].value;
}
}
return null;
}
- set {
+ set
+ {
if (key == null)
{
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<TValue>(value, ExceptionArgument.value);
- try {
+ try
+ {
TKey tempKey = (TKey)key;
- try {
- this[tempKey] = (TValue)value;
+ try
+ {
+ this[tempKey] = (TValue)value;
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(TValue));
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(TValue));
}
}
- catch (InvalidCastException) {
+ catch (InvalidCastException)
+ {
ThrowHelper.ThrowWrongKeyTypeArgumentException(key, typeof(TKey));
}
}
}
- private static bool IsCompatibleKey(object key) {
- if( key == null) {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- }
- return (key is TKey);
+ private static bool IsCompatibleKey(object key)
+ {
+ if (key == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ }
+ return (key is TKey);
}
-
- void IDictionary.Add(object key, object value) {
+
+ void IDictionary.Add(object key, object value)
+ {
if (key == null)
{
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<TValue>(value, ExceptionArgument.value);
- try {
+ try
+ {
TKey tempKey = (TKey)key;
- try {
+ try
+ {
Add(tempKey, (TValue)value);
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(TValue));
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(TValue));
}
}
- catch (InvalidCastException) {
+ catch (InvalidCastException)
+ {
ThrowHelper.ThrowWrongKeyTypeArgumentException(key, typeof(TKey));
}
}
-
- bool IDictionary.Contains(object key) {
- if(IsCompatibleKey(key)) {
+
+ bool IDictionary.Contains(object key)
+ {
+ if (IsCompatibleKey(key))
+ {
return ContainsKey((TKey)key);
}
-
+
return false;
}
-
- IDictionaryEnumerator IDictionary.GetEnumerator() {
+
+ IDictionaryEnumerator IDictionary.GetEnumerator()
+ {
return new Enumerator(this, Enumerator.DictEntry);
}
-
- void IDictionary.Remove(object key) {
- if(IsCompatibleKey(key)) {
+
+ void IDictionary.Remove(object key)
+ {
+ if (IsCompatibleKey(key))
+ {
Remove((TKey)key);
}
}
[Serializable]
- public struct Enumerator: IEnumerator<KeyValuePair<TKey,TValue>>,
+ public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>,
IDictionaryEnumerator
{
- private Dictionary<TKey,TValue> dictionary;
+ private Dictionary<TKey, TValue> dictionary;
private int version;
private int index;
- private KeyValuePair<TKey,TValue> current;
+ private KeyValuePair<TKey, TValue> current;
private int getEnumeratorRetType; // What should Enumerator.Current return?
-
+
internal const int DictEntry = 1;
internal const int KeyValuePair = 2;
- internal Enumerator(Dictionary<TKey,TValue> dictionary, int getEnumeratorRetType) {
+ internal Enumerator(Dictionary<TKey, TValue> dictionary, int getEnumeratorRetType)
+ {
this.dictionary = dictionary;
version = dictionary.version;
index = 0;
@@ -732,15 +944,19 @@ namespace System.Collections.Generic {
current = new KeyValuePair<TKey, TValue>();
}
- public bool MoveNext() {
- if (version != dictionary.version) {
+ public bool MoveNext()
+ {
+ if (version != dictionary.version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
// 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
- while ((uint)index < (uint)dictionary.count) {
- if (dictionary.entries[index].hashCode >= 0) {
+ while ((uint)index < (uint)dictionary.count)
+ {
+ if (dictionary.entries[index].hashCode >= 0)
+ {
current = new KeyValuePair<TKey, TValue>(dictionary.entries[index].key, dictionary.entries[index].value);
index++;
return true;
@@ -753,187 +969,236 @@ namespace System.Collections.Generic {
return false;
}
- public KeyValuePair<TKey,TValue> Current {
+ public KeyValuePair<TKey, TValue> Current
+ {
get { return current; }
}
- public void Dispose() {
+ public void Dispose()
+ {
}
- object IEnumerator.Current {
- get {
- if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
- }
+ object IEnumerator.Current
+ {
+ get
+ {
+ if (index == 0 || (index == dictionary.count + 1))
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ }
- if (getEnumeratorRetType == DictEntry) {
+ if (getEnumeratorRetType == DictEntry)
+ {
return new System.Collections.DictionaryEntry(current.Key, current.Value);
- } else {
+ }
+ else
+ {
return new KeyValuePair<TKey, TValue>(current.Key, current.Value);
}
}
}
- void IEnumerator.Reset() {
- if (version != dictionary.version) {
+ void IEnumerator.Reset()
+ {
+ if (version != dictionary.version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
index = 0;
- current = new KeyValuePair<TKey, TValue>();
+ current = new KeyValuePair<TKey, TValue>();
}
- DictionaryEntry IDictionaryEnumerator.Entry {
- get {
- if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
- }
-
- return new DictionaryEntry(current.Key, current.Value);
+ DictionaryEntry IDictionaryEnumerator.Entry
+ {
+ get
+ {
+ if (index == 0 || (index == dictionary.count + 1))
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ }
+
+ return new DictionaryEntry(current.Key, current.Value);
}
}
- object IDictionaryEnumerator.Key {
- get {
- if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
- }
-
- return current.Key;
+ object IDictionaryEnumerator.Key
+ {
+ get
+ {
+ if (index == 0 || (index == dictionary.count + 1))
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ }
+
+ return current.Key;
}
}
- object IDictionaryEnumerator.Value {
- get {
- if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
- }
-
- return current.Value;
+ object IDictionaryEnumerator.Value
+ {
+ get
+ {
+ if (index == 0 || (index == dictionary.count + 1))
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ }
+
+ return current.Value;
}
}
}
[DebuggerTypeProxy(typeof(Mscorlib_DictionaryKeyCollectionDebugView<,>))]
- [DebuggerDisplay("Count = {Count}")]
+ [DebuggerDisplay("Count = {Count}")]
[Serializable]
- public sealed class KeyCollection: ICollection<TKey>, ICollection, IReadOnlyCollection<TKey>
+ public sealed class KeyCollection : ICollection<TKey>, ICollection, IReadOnlyCollection<TKey>
{
- private Dictionary<TKey,TValue> dictionary;
+ private Dictionary<TKey, TValue> dictionary;
- public KeyCollection(Dictionary<TKey,TValue> dictionary) {
- if (dictionary == null) {
+ public KeyCollection(Dictionary<TKey, TValue> dictionary)
+ {
+ if (dictionary == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
}
this.dictionary = dictionary;
}
- public Enumerator GetEnumerator() {
+ public Enumerator GetEnumerator()
+ {
return new Enumerator(dictionary);
}
- public void CopyTo(TKey[] array, int index) {
- if (array == null) {
+ public void CopyTo(TKey[] array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (index < 0 || index > array.Length) {
+ if (index < 0 || index > array.Length)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < dictionary.Count) {
+ if (array.Length - index < dictionary.Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
-
+
int count = dictionary.count;
Entry[] entries = dictionary.entries;
- for (int i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++)
+ {
if (entries[i].hashCode >= 0) array[index++] = entries[i].key;
}
}
- public int Count {
+ public int Count
+ {
get { return dictionary.Count; }
}
- bool ICollection<TKey>.IsReadOnly {
+ bool ICollection<TKey>.IsReadOnly
+ {
get { return true; }
}
- void ICollection<TKey>.Add(TKey item){
+ void ICollection<TKey>.Add(TKey item)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
}
-
- void ICollection<TKey>.Clear(){
+
+ void ICollection<TKey>.Clear()
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
}
- bool ICollection<TKey>.Contains(TKey item){
+ bool ICollection<TKey>.Contains(TKey item)
+ {
return dictionary.ContainsKey(item);
}
- bool ICollection<TKey>.Remove(TKey item){
+ bool ICollection<TKey>.Remove(TKey item)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
return false;
}
-
- IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator() {
+
+ IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator()
+ {
return new Enumerator(dictionary);
}
- IEnumerator IEnumerable.GetEnumerator() {
- return new Enumerator(dictionary);
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return new Enumerator(dictionary);
}
- void ICollection.CopyTo(Array array, int index) {
- if (array==null) {
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (array.Rank != 1) {
+ if (array.Rank != 1)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if( array.GetLowerBound(0) != 0 ) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
- if (index < 0 || index > array.Length) {
+ if (index < 0 || index > array.Length)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < dictionary.Count) {
+ if (array.Length - index < dictionary.Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
-
+
TKey[] keys = array as TKey[];
- if (keys != null) {
+ if (keys != null)
+ {
CopyTo(keys, index);
}
- else {
+ else
+ {
object[] objects = array as object[];
- if (objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
-
+
int count = dictionary.count;
Entry[] entries = dictionary.entries;
- try {
- for (int i = 0; i < count; i++) {
+ try
+ {
+ for (int i = 0; i < count; i++)
+ {
if (entries[i].hashCode >= 0) objects[index++] = entries[i].key;
}
- }
- catch(ArrayTypeMismatchException) {
+ }
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- Object ICollection.SyncRoot {
+ Object ICollection.SyncRoot
+ {
get { return ((ICollection)dictionary).SyncRoot; }
}
@@ -944,24 +1209,30 @@ namespace System.Collections.Generic {
private int index;
private int version;
private TKey currentKey;
-
- internal Enumerator(Dictionary<TKey, TValue> dictionary) {
+
+ internal Enumerator(Dictionary<TKey, TValue> dictionary)
+ {
this.dictionary = dictionary;
version = dictionary.version;
index = 0;
- currentKey = default(TKey);
+ currentKey = default(TKey);
}
- public void Dispose() {
+ public void Dispose()
+ {
}
- public bool MoveNext() {
- if (version != dictionary.version) {
+ public bool MoveNext()
+ {
+ if (version != dictionary.version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
- while ((uint)index < (uint)dictionary.count) {
- if (dictionary.entries[index].hashCode >= 0) {
+ while ((uint)index < (uint)dictionary.count)
+ {
+ if (dictionary.entries[index].hashCode >= 0)
+ {
currentKey = dictionary.entries[index].key;
index++;
return true;
@@ -973,153 +1244,189 @@ namespace System.Collections.Generic {
currentKey = default(TKey);
return false;
}
-
- public TKey Current {
- get {
+
+ public TKey Current
+ {
+ get
+ {
return currentKey;
}
}
- Object System.Collections.IEnumerator.Current {
- get {
- if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
- }
-
+ Object System.Collections.IEnumerator.Current
+ {
+ get
+ {
+ if (index == 0 || (index == dictionary.count + 1))
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ }
+
return currentKey;
}
}
-
- void System.Collections.IEnumerator.Reset() {
- if (version != dictionary.version) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
+
+ void System.Collections.IEnumerator.Reset()
+ {
+ if (version != dictionary.version)
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
- index = 0;
+ index = 0;
currentKey = default(TKey);
}
- }
+ }
}
[DebuggerTypeProxy(typeof(Mscorlib_DictionaryValueCollectionDebugView<,>))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
- public sealed class ValueCollection: ICollection<TValue>, ICollection, IReadOnlyCollection<TValue>
+ public sealed class ValueCollection : ICollection<TValue>, ICollection, IReadOnlyCollection<TValue>
{
- private Dictionary<TKey,TValue> dictionary;
+ private Dictionary<TKey, TValue> dictionary;
- public ValueCollection(Dictionary<TKey,TValue> dictionary) {
- if (dictionary == null) {
+ public ValueCollection(Dictionary<TKey, TValue> dictionary)
+ {
+ if (dictionary == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
}
this.dictionary = dictionary;
}
- public Enumerator GetEnumerator() {
- return new Enumerator(dictionary);
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(dictionary);
}
- public void CopyTo(TValue[] array, int index) {
- if (array == null) {
+ public void CopyTo(TValue[] array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (index < 0 || index > array.Length) {
+ if (index < 0 || index > array.Length)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < dictionary.Count) {
+ if (array.Length - index < dictionary.Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
-
+
int count = dictionary.count;
Entry[] entries = dictionary.entries;
- for (int i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++)
+ {
if (entries[i].hashCode >= 0) array[index++] = entries[i].value;
}
}
- public int Count {
+ public int Count
+ {
get { return dictionary.Count; }
}
- bool ICollection<TValue>.IsReadOnly {
+ bool ICollection<TValue>.IsReadOnly
+ {
get { return true; }
}
- void ICollection<TValue>.Add(TValue item){
+ void ICollection<TValue>.Add(TValue item)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
}
- bool ICollection<TValue>.Remove(TValue item){
+ bool ICollection<TValue>.Remove(TValue item)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
return false;
}
- void ICollection<TValue>.Clear(){
+ void ICollection<TValue>.Clear()
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
}
- bool ICollection<TValue>.Contains(TValue item){
+ bool ICollection<TValue>.Contains(TValue item)
+ {
return dictionary.ContainsValue(item);
}
- IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator() {
+ IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator()
+ {
return new Enumerator(dictionary);
}
- IEnumerator IEnumerable.GetEnumerator() {
- return new Enumerator(dictionary);
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return new Enumerator(dictionary);
}
- void ICollection.CopyTo(Array array, int index) {
- if (array == null) {
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (array.Rank != 1) {
+ if (array.Rank != 1)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if( array.GetLowerBound(0) != 0 ) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
- if (index < 0 || index > array.Length) {
+ if (index < 0 || index > 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 (values != null)
+ {
CopyTo(values, index);
}
- else {
+ else
+ {
object[] objects = array as object[];
- if (objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
int count = dictionary.count;
Entry[] entries = dictionary.entries;
- try {
- for (int i = 0; i < count; i++) {
+ try
+ {
+ for (int i = 0; i < count; i++)
+ {
if (entries[i].hashCode >= 0) objects[index++] = entries[i].value;
}
}
- catch(ArrayTypeMismatchException) {
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- Object ICollection.SyncRoot {
+ Object ICollection.SyncRoot
+ {
get { return ((ICollection)dictionary).SyncRoot; }
}
@@ -1130,24 +1437,30 @@ namespace System.Collections.Generic {
private int index;
private int version;
private TValue currentValue;
-
- internal Enumerator(Dictionary<TKey, TValue> dictionary) {
+
+ internal Enumerator(Dictionary<TKey, TValue> dictionary)
+ {
this.dictionary = dictionary;
version = dictionary.version;
index = 0;
currentValue = default(TValue);
}
- public void Dispose() {
+ public void Dispose()
+ {
}
- public bool MoveNext() {
- if (version != dictionary.version) {
+ public bool MoveNext()
+ {
+ if (version != dictionary.version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
-
- while ((uint)index < (uint)dictionary.count) {
- if (dictionary.entries[index].hashCode >= 0) {
+
+ while ((uint)index < (uint)dictionary.count)
+ {
+ if (dictionary.entries[index].hashCode >= 0)
+ {
currentValue = dictionary.entries[index].value;
index++;
return true;
@@ -1158,28 +1471,35 @@ namespace System.Collections.Generic {
currentValue = default(TValue);
return false;
}
-
- public TValue Current {
- get {
+
+ public TValue Current
+ {
+ get
+ {
return currentValue;
}
}
- Object System.Collections.IEnumerator.Current {
- get {
- if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
- }
-
+ Object System.Collections.IEnumerator.Current
+ {
+ get
+ {
+ if (index == 0 || (index == dictionary.count + 1))
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ }
+
return currentValue;
}
}
-
- void System.Collections.IEnumerator.Reset() {
- if (version != dictionary.version) {
+
+ void System.Collections.IEnumerator.Reset()
+ {
+ if (version != dictionary.version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
- index = 0;
+ index = 0;
currentValue = default(TValue);
}
}
diff --git a/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs b/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs
index 0f9259d2f3..0cd1bc1c12 100644
--- a/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs
+++ b/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs
@@ -7,117 +7,56 @@ using System.Collections;
using System.Collections.Generic;
using System.Security;
+using System.Globalization;
+using System.Runtime;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.Contracts;
+
namespace System.Collections.Generic
{
- using System.Globalization;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Diagnostics.Contracts;
-
[Serializable]
[TypeDependencyAttribute("System.Collections.Generic.ObjectEqualityComparer`1")]
public abstract class EqualityComparer<T> : IEqualityComparer, IEqualityComparer<T>
{
- static readonly EqualityComparer<T> defaultComparer = CreateComparer();
-
- public static EqualityComparer<T> Default {
- get {
- Contract.Ensures(Contract.Result<EqualityComparer<T>>() != null);
- return defaultComparer;
- }
- }
-
- //
- // Note that logic in this method is replicated in vm\compile.cpp to ensure that NGen
- // saves the right instantiations
- //
- private static EqualityComparer<T> CreateComparer()
- {
- Contract.Ensures(Contract.Result<EqualityComparer<T>>() != null);
-
- object result = null;
- RuntimeType t = (RuntimeType)typeof(T);
-
- // Specialize type byte for performance reasons
- if (t == typeof(byte)) {
- result = new ByteEqualityComparer();
- }
- // If T implements IEquatable<T> return a GenericEqualityComparer<T>
- else if (typeof(IEquatable<T>).IsAssignableFrom(t))
- {
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer<int>), t);
- }
- else if (default(T) == null) // Reference type/Nullable
- {
- // If T is a Nullable<U> where U implements IEquatable<U> return a NullableEqualityComparer<U>
- if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) {
- RuntimeType u = (RuntimeType)t.GetGenericArguments()[0];
- if (typeof(IEquatable<>).MakeGenericType(u).IsAssignableFrom(u)) {
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableEqualityComparer<int>), u);
- }
- }
- }
- // See the METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST and METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST_LONG cases in getILIntrinsicImplementation
- else if (t.IsEnum) {
- TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(t));
-
- // Depending on the enum type, we need to special case the comparers so that we avoid boxing
- // Note: We have different comparers for Short and SByte because for those types we need to make sure we call GetHashCode on the actual underlying type as the
- // implementation of GetHashCode is more complex than for the other types.
- switch (underlyingTypeCode) {
- case TypeCode.Int16: // short
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ShortEnumEqualityComparer<short>), t);
- break;
- case TypeCode.SByte:
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(SByteEnumEqualityComparer<sbyte>), t);
- break;
- case TypeCode.Int32:
- case TypeCode.UInt32:
- case TypeCode.Byte:
- case TypeCode.UInt16: //ushort
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer<int>), t);
- break;
- case TypeCode.Int64:
- case TypeCode.UInt64:
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(LongEnumEqualityComparer<long>), t);
- break;
- }
- }
-
- return result != null ?
- (EqualityComparer<T>)result :
- new ObjectEqualityComparer<T>(); // Fallback to ObjectEqualityComparer, which uses boxing
- }
+ // To minimize generic instantiation overhead of creating the comparer per type, we keep the generic portion of the code as small
+ // as possible and define most of the creation logic in a non-generic class.
+ public static EqualityComparer<T> Default { get; } = (EqualityComparer<T>)ComparerHelpers.CreateDefaultEqualityComparer(typeof(T));
[Pure]
public abstract bool Equals(T x, T y);
[Pure]
public abstract int GetHashCode(T obj);
- internal virtual int IndexOf(T[] array, T value, int startIndex, int count) {
+ internal virtual int IndexOf(T[] array, T value, int startIndex, int count)
+ {
int endIndex = startIndex + count;
- for (int i = startIndex; i < endIndex; i++) {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (Equals(array[i], value)) return i;
}
return -1;
}
- internal virtual int LastIndexOf(T[] array, T value, int startIndex, int count) {
+ internal virtual int LastIndexOf(T[] array, T value, int startIndex, int count)
+ {
int endIndex = startIndex - count + 1;
- for (int i = startIndex; i >= endIndex; i--) {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (Equals(array[i], value)) return i;
}
return -1;
}
- int IEqualityComparer.GetHashCode(object obj) {
+ int IEqualityComparer.GetHashCode(object obj)
+ {
if (obj == null) return 0;
if (obj is T) return GetHashCode((T)obj);
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArgumentForComparison);
- return 0;
- }
+ return 0;
+ }
- bool IEqualityComparer.Equals(object x, object y) {
+ bool IEqualityComparer.Equals(object x, object y)
+ {
if (x == y) return true;
if (x == null || y == null) return false;
if ((x is T) && (y is T)) return Equals((T)x, (T)y);
@@ -129,11 +68,13 @@ namespace System.Collections.Generic
// The methods in this class look identical to the inherited methods, but the calls
// to Equal bind to IEquatable<T>.Equals(T) instead of Object.Equals(Object)
[Serializable]
- internal class GenericEqualityComparer<T>: EqualityComparer<T> where T: IEquatable<T>
+ internal class GenericEqualityComparer<T> : EqualityComparer<T> where T : IEquatable<T>
{
[Pure]
- public override bool Equals(T x, T y) {
- if (x != null) {
+ public override bool Equals(T x, T y)
+ {
+ if (x != null)
+ {
if (y != null) return x.Equals(y);
return false;
}
@@ -144,30 +85,40 @@ namespace System.Collections.Generic
[Pure]
public override int GetHashCode(T obj) => obj?.GetHashCode() ?? 0;
- internal override int IndexOf(T[] array, T value, int startIndex, int count) {
+ internal override int IndexOf(T[] array, T value, int startIndex, int count)
+ {
int endIndex = startIndex + count;
- if (value == null) {
- for (int i = startIndex; i < endIndex; i++) {
+ if (value == null)
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (array[i] == null) return i;
}
}
- else {
- for (int i = startIndex; i < endIndex; i++) {
+ else
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (array[i] != null && array[i].Equals(value)) return i;
}
}
return -1;
}
- internal override int LastIndexOf(T[] array, T value, int startIndex, int count) {
+ internal override int LastIndexOf(T[] array, T value, int startIndex, int count)
+ {
int endIndex = startIndex - count + 1;
- if (value == null) {
- for (int i = startIndex; i >= endIndex; i--) {
+ if (value == null)
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (array[i] == null) return i;
}
}
- else {
- for (int i = startIndex; i >= endIndex; i--) {
+ else
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (array[i] != null && array[i].Equals(value)) return i;
}
}
@@ -188,8 +139,10 @@ namespace System.Collections.Generic
internal sealed class NullableEqualityComparer<T> : EqualityComparer<T?> where T : struct, IEquatable<T>
{
[Pure]
- public override bool Equals(T? x, T? y) {
- if (x.HasValue) {
+ public override bool Equals(T? x, T? y)
+ {
+ if (x.HasValue)
+ {
if (y.HasValue) return x.value.Equals(y.value);
return false;
}
@@ -200,30 +153,40 @@ namespace System.Collections.Generic
[Pure]
public override int GetHashCode(T? obj) => obj.GetHashCode();
- internal override int IndexOf(T?[] array, T? value, int startIndex, int count) {
+ internal override int IndexOf(T?[] array, T? value, int startIndex, int count)
+ {
int endIndex = startIndex + count;
- if (!value.HasValue) {
- for (int i = startIndex; i < endIndex; i++) {
+ if (!value.HasValue)
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (!array[i].HasValue) return i;
}
}
- else {
- for (int i = startIndex; i < endIndex; i++) {
+ else
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (array[i].HasValue && array[i].value.Equals(value.value)) return i;
}
}
return -1;
}
- internal override int LastIndexOf(T?[] array, T? value, int startIndex, int count) {
+ internal override int LastIndexOf(T?[] array, T? value, int startIndex, int count)
+ {
int endIndex = startIndex - count + 1;
- if (!value.HasValue) {
- for (int i = startIndex; i >= endIndex; i--) {
+ if (!value.HasValue)
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (!array[i].HasValue) return i;
}
}
- else {
- for (int i = startIndex; i >= endIndex; i--) {
+ else
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (array[i].HasValue && array[i].value.Equals(value.value)) return i;
}
}
@@ -239,11 +202,13 @@ namespace System.Collections.Generic
}
[Serializable]
- internal sealed class ObjectEqualityComparer<T>: EqualityComparer<T>
+ internal sealed class ObjectEqualityComparer<T> : EqualityComparer<T>
{
[Pure]
- public override bool Equals(T x, T y) {
- if (x != null) {
+ public override bool Equals(T x, T y)
+ {
+ if (x != null)
+ {
if (y != null) return x.Equals(y);
return false;
}
@@ -254,30 +219,40 @@ namespace System.Collections.Generic
[Pure]
public override int GetHashCode(T obj) => obj?.GetHashCode() ?? 0;
- internal override int IndexOf(T[] array, T value, int startIndex, int count) {
+ internal override int IndexOf(T[] array, T value, int startIndex, int count)
+ {
int endIndex = startIndex + count;
- if (value == null) {
- for (int i = startIndex; i < endIndex; i++) {
+ if (value == null)
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (array[i] == null) return i;
}
}
- else {
- for (int i = startIndex; i < endIndex; i++) {
+ else
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (array[i] != null && array[i].Equals(value)) return i;
}
}
return -1;
}
- internal override int LastIndexOf(T[] array, T value, int startIndex, int count) {
+ internal override int LastIndexOf(T[] array, T value, int startIndex, int count)
+ {
int endIndex = startIndex - count + 1;
- if (value == null) {
- for (int i = startIndex; i >= endIndex; i--) {
+ if (value == null)
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (array[i] == null) return i;
}
}
- else {
- for (int i = startIndex; i >= endIndex; i--) {
+ else
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (array[i] != null && array[i].Equals(value)) return i;
}
}
@@ -299,20 +274,25 @@ namespace System.Collections.Generic
// keep the perofrmance not affected till we hit collision threshold and then we switch to the comparer which is using
// randomized string hashing GenericEqualityComparer<string>
[Serializable]
- internal class NonRandomizedStringEqualityComparer : GenericEqualityComparer<string> {
- static IEqualityComparer<string> s_nonRandomizedComparer;
-
- internal static new IEqualityComparer<string> Default {
- get {
- if (s_nonRandomizedComparer == null) {
- s_nonRandomizedComparer = new NonRandomizedStringEqualityComparer();
- }
- return s_nonRandomizedComparer;
+ internal class NonRandomizedStringEqualityComparer : GenericEqualityComparer<string>
+ {
+ private static IEqualityComparer<string> s_nonRandomizedComparer;
+
+ internal static new IEqualityComparer<string> Default
+ {
+ get
+ {
+ if (s_nonRandomizedComparer == null)
+ {
+ s_nonRandomizedComparer = new NonRandomizedStringEqualityComparer();
+ }
+ return s_nonRandomizedComparer;
}
}
[Pure]
- public override int GetHashCode(string obj) {
+ public override int GetHashCode(string obj)
+ {
if (obj == null) return 0;
return obj.GetLegacyNonRandomizedHashCode();
}
@@ -321,37 +301,43 @@ namespace System.Collections.Generic
// Performance of IndexOf on byte array is very important for some scenarios.
// We will call the C runtime function memchr, which is optimized.
[Serializable]
- internal sealed class ByteEqualityComparer: EqualityComparer<byte>
+ internal sealed class ByteEqualityComparer : EqualityComparer<byte>
{
[Pure]
- public override bool Equals(byte x, byte y) {
+ public override bool Equals(byte x, byte y)
+ {
return x == y;
}
[Pure]
- public override int GetHashCode(byte b) {
+ public override int GetHashCode(byte b)
+ {
return b.GetHashCode();
}
- internal unsafe override int IndexOf(byte[] array, byte value, int startIndex, int count) {
- if (array==null)
+ internal unsafe override int IndexOf(byte[] array, byte value, int startIndex, int count)
+ {
+ if (array == null)
throw new ArgumentNullException(nameof(array));
if (startIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
if (count > array.Length - startIndex)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
if (count == 0) return -1;
- fixed (byte* pbytes = array) {
+ fixed (byte* pbytes = array)
+ {
return Buffer.IndexOfByte(pbytes, value, startIndex, count);
}
}
- internal override int LastIndexOf(byte[] array, byte value, int startIndex, int count) {
+ internal override int LastIndexOf(byte[] array, byte value, int startIndex, int count)
+ {
int endIndex = startIndex - count + 1;
- for (int i = startIndex; i >= endIndex; i--) {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (array[i] == value) return i;
}
return -1;
@@ -362,21 +348,23 @@ namespace System.Collections.Generic
obj != null && GetType() == obj.GetType();
public override int GetHashCode() =>
- GetType().GetHashCode();
+ GetType().GetHashCode();
}
[Serializable]
internal class EnumEqualityComparer<T> : EqualityComparer<T> where T : struct
{
[Pure]
- public override bool Equals(T x, T y) {
+ public override bool Equals(T x, T y)
+ {
int x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(x);
int y_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(y);
return x_final == y_final;
}
[Pure]
- public override int GetHashCode(T obj) {
+ public override int GetHashCode(T obj)
+ {
int x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(obj);
return x_final.GetHashCode();
}
@@ -421,7 +409,8 @@ namespace System.Collections.Generic
public SByteEnumEqualityComparer() { }
[Pure]
- public override int GetHashCode(T obj) {
+ public override int GetHashCode(T obj)
+ {
int x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(obj);
return ((sbyte)x_final).GetHashCode();
}
@@ -433,7 +422,8 @@ namespace System.Collections.Generic
public ShortEnumEqualityComparer() { }
[Pure]
- public override int GetHashCode(T obj) {
+ public override int GetHashCode(T obj)
+ {
int x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(obj);
return ((short)x_final).GetHashCode();
}
@@ -443,14 +433,16 @@ namespace System.Collections.Generic
internal sealed class LongEnumEqualityComparer<T> : EqualityComparer<T> where T : struct
{
[Pure]
- public override bool Equals(T x, T y) {
+ public override bool Equals(T x, T y)
+ {
long x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCastLong(x);
long y_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCastLong(y);
return x_final == y_final;
}
[Pure]
- public override int GetHashCode(T obj) {
+ public override int GetHashCode(T obj)
+ {
long x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCastLong(obj);
return x_final.GetHashCode();
}
diff --git a/src/mscorlib/src/System/Collections/Generic/ICollection.cs b/src/mscorlib/src/System/Collections/Generic/ICollection.cs
deleted file mode 100644
index 741e8cc79b..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/ICollection.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: ICollection
-**
-**
-**
-**
-** Purpose: Base interface for all generic collections.
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
- using System;
- using System.Runtime.CompilerServices;
- using System.Diagnostics.Contracts;
-
- // Base interface for all collections, defining enumerators, size, and
- // synchronization methods.
-
- // Note that T[] : IList<T>, and we want to ensure that if you use
- // IList<YourValueType>, we ensure a YourValueType[] can be used
- // without jitting. Hence the TypeDependencyAttribute on SZArrayHelper.
- // This is a special workaround internally though - see VM\compile.cpp.
- // The same attribute is on IEnumerable<T> and ICollection<T>.
- [TypeDependencyAttribute("System.SZArrayHelper")]
- public interface ICollection<T> : IEnumerable<T>
- {
- // Number of items in the collections.
- int Count { get; }
-
- bool IsReadOnly { get; }
-
- void Add(T item);
-
- void Clear();
-
- bool Contains(T item);
-
- // CopyTo copies a collection into an Array, starting at a particular
- // index into the array.
- //
- void CopyTo(T[] array, int arrayIndex);
-
- //void CopyTo(int sourceIndex, T[] destinationArray, int destinationIndex, int count);
-
- bool Remove(T item);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IComparer.cs b/src/mscorlib/src/System/Collections/Generic/IComparer.cs
deleted file mode 100644
index 7b9e97ff0e..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IComparer.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IComparer
-**
-**
-**
-**
-** Purpose: Interface for comparing two generic Objects.
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
-
- using System;
- // The generic IComparer interface implements a method that compares
- // two objects. It is used in conjunction with the Sort and
- // BinarySearch methods on the Array, List, and SortedList classes.
- public interface IComparer<in T>
- {
- // Compares two objects. An implementation of this method must return a
- // value less than zero if x is less than y, zero if x is equal to y, or a
- // value greater than zero if x is greater than y.
- //
- int Compare(T x, T y);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IDictionary.cs b/src/mscorlib/src/System/Collections/Generic/IDictionary.cs
deleted file mode 100644
index 2a2da944d3..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IDictionary.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IDictionary
-**
-**
-**
-**
-** Purpose: Base interface for all generic dictionaries.
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
- using System;
- using System.Diagnostics.Contracts;
-
- // An IDictionary is a possibly unordered set of key-value pairs.
- // Keys can be any non-null object. Values can be any object.
- // You can look up a value in an IDictionary via the default indexed
- // property, Items.
- public interface IDictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>>
- {
- // Interfaces are not serializable
- // The Item property provides methods to read and edit entries
- // in the Dictionary.
- TValue this[TKey key] {
- get;
- set;
- }
-
- // Returns a collections of the keys in this dictionary.
- ICollection<TKey> Keys {
- get;
- }
-
- // Returns a collections of the values in this dictionary.
- ICollection<TValue> Values {
- get;
- }
-
- // Returns whether this dictionary contains a particular key.
- //
- bool ContainsKey(TKey key);
-
- // Adds a key-value pair to the dictionary.
- //
- void Add(TKey key, TValue value);
-
- // Removes a particular key from the dictionary.
- //
- bool Remove(TKey key);
-
- bool TryGetValue(TKey key, out TValue value);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IEnumerable.cs b/src/mscorlib/src/System/Collections/Generic/IEnumerable.cs
deleted file mode 100644
index 67f35ce675..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IEnumerable.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IEnumerable
-**
-**
-**
-**
-** Purpose: Interface for providing generic IEnumerators
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
- using System;
- using System.Collections;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Diagnostics.Contracts;
-
- // Implement this interface if you need to support foreach semantics.
-
- // Note that T[] : IList<T>, and we want to ensure that if you use
- // IList<YourValueType>, we ensure a YourValueType[] can be used
- // without jitting. Hence the TypeDependencyAttribute on SZArrayHelper.
- // This is a special workaround internally though - see VM\compile.cpp.
- // The same attribute is on IList<T> and ICollection<T>.
- [TypeDependencyAttribute("System.SZArrayHelper")]
- public interface IEnumerable<out T> : IEnumerable
- {
- // Returns an IEnumerator for this enumerable Object. The enumerator provides
- // a simple way to access all the contents of a collection.
- /// <include file='doc\IEnumerable.uex' path='docs/doc[@for="IEnumerable.GetEnumerator"]/*' />
- new IEnumerator<T> GetEnumerator();
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IEnumerator.cs b/src/mscorlib/src/System/Collections/Generic/IEnumerator.cs
deleted file mode 100644
index 335616757b..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IEnumerator.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IEnumerator
-**
-**
-**
-**
-** Purpose: Base interface for all generic enumerators.
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
- using System;
- using System.Runtime.InteropServices;
-
- // Base interface for all generic enumerators, providing a simple approach
- // to iterating over a collection.
- public interface IEnumerator<out T> : IDisposable, IEnumerator
- {
- // Returns the current element of the enumeration. The returned value is
- // undefined before the first call to MoveNext and following a
- // call to MoveNext that returned false. Multiple calls to
- // GetCurrent with no intervening calls to MoveNext
- // will return the same object.
- //
- /// <include file='doc\IEnumerator.uex' path='docs/doc[@for="IEnumerator.Current"]/*' />
- new T Current {
- get;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IEqualityComparer.cs b/src/mscorlib/src/System/Collections/Generic/IEqualityComparer.cs
deleted file mode 100644
index b6ac3be006..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IEqualityComparer.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-//
-
-namespace System.Collections.Generic {
- using System;
-
- // The generic IEqualityComparer interface implements methods to if check two objects are equal
- // and generate Hashcode for an object.
- // It is use in Dictionary class.
- public interface IEqualityComparer<in T>
- {
- bool Equals(T x, T y);
- int GetHashCode(T obj);
- }
-}
-
diff --git a/src/mscorlib/src/System/Collections/Generic/IList.cs b/src/mscorlib/src/System/Collections/Generic/IList.cs
deleted file mode 100644
index 75ca0a9b00..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IList.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IList
-**
-**
-**
-**
-** Purpose: Base interface for all generic lists.
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
-
- using System;
- using System.Collections;
- using System.Runtime.CompilerServices;
- using System.Diagnostics.Contracts;
-
- // An IList is an ordered collection of objects. The exact ordering
- // is up to the implementation of the list, ranging from a sorted
- // order to insertion order.
-
- // Note that T[] : IList<T>, and we want to ensure that if you use
- // IList<YourValueType>, we ensure a YourValueType[] can be used
- // without jitting. Hence the TypeDependencyAttribute on SZArrayHelper.
- // This is a special workaround internally though - see VM\compile.cpp.
- // The same attribute is on IEnumerable<T> and ICollection<T>.
- [TypeDependencyAttribute("System.SZArrayHelper")]
- public interface IList<T> : ICollection<T>
- {
- // The Item property provides methods to read and edit entries in the List.
- T this[int index] {
- get;
- set;
- }
-
- // Returns the index of a particular item, if it is in the list.
- // Returns -1 if the item isn't in the list.
- int IndexOf(T item);
-
- // Inserts value into the list at position index.
- // index must be non-negative and less than or equal to the
- // number of elements in the list. If index equals the number
- // of items in the list, then value is appended to the end.
- void Insert(int index, T item);
-
- // Removes the item at position index.
- void RemoveAt(int index);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IReadOnlyCollection.cs b/src/mscorlib/src/System/Collections/Generic/IReadOnlyCollection.cs
deleted file mode 100644
index 13bc718760..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IReadOnlyCollection.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IReadOnlyCollection<T>
-**
-**
-**
-** Purpose: Base interface for read-only generic lists.
-**
-===========================================================*/
-using System;
-using System.Diagnostics.Contracts;
-using System.Runtime.CompilerServices;
-
-namespace System.Collections.Generic
-{
-
- // Provides a read-only, covariant view of a generic list.
-
- // Note that T[] : IReadOnlyList<T>, and we want to ensure that if you use
- // IList<YourValueType>, we ensure a YourValueType[] can be used
- // without jitting. Hence the TypeDependencyAttribute on SZArrayHelper.
- // This is a special workaround internally though - see VM\compile.cpp.
- // The same attribute is on IList<T>, IEnumerable<T>, ICollection<T>, and IReadOnlyList<T>.
- [TypeDependencyAttribute("System.SZArrayHelper")]
- // If we ever implement more interfaces on IReadOnlyCollection, we should also update RuntimeTypeCache.PopulateInterfaces() in rttype.cs
- public interface IReadOnlyCollection<out T> : IEnumerable<T>
- {
- int Count { get; }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IReadOnlyDictionary.cs b/src/mscorlib/src/System/Collections/Generic/IReadOnlyDictionary.cs
deleted file mode 100644
index 3603b9a4ea..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IReadOnlyDictionary.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IReadOnlyDictionary<TKey, TValue>
-**
-**
-**
-** Purpose: Base interface for read-only generic dictionaries.
-**
-===========================================================*/
-using System;
-using System.Diagnostics.Contracts;
-
-namespace System.Collections.Generic
-{
- // Provides a read-only view of a generic dictionary.
- public interface IReadOnlyDictionary<TKey, TValue> : IReadOnlyCollection<KeyValuePair<TKey, TValue>>
- {
- bool ContainsKey(TKey key);
- bool TryGetValue(TKey key, out TValue value);
-
- TValue this[TKey key] { get; }
- IEnumerable<TKey> Keys { get; }
- IEnumerable<TValue> Values { get; }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IReadOnlyList.cs b/src/mscorlib/src/System/Collections/Generic/IReadOnlyList.cs
deleted file mode 100644
index 77366f0b2f..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IReadOnlyList.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IReadOnlyList<T>
-**
-**
-**
-** Purpose: Base interface for read-only generic lists.
-**
-===========================================================*/
-using System;
-using System.Diagnostics.Contracts;
-using System.Runtime.CompilerServices;
-
-namespace System.Collections.Generic
-{
-
- // Provides a read-only, covariant view of a generic list.
-
- // Note that T[] : IReadOnlyList<T>, and we want to ensure that if you use
- // IList<YourValueType>, we ensure a YourValueType[] can be used
- // without jitting. Hence the TypeDependencyAttribute on SZArrayHelper.
- // This is a special workaround internally though - see VM\compile.cpp.
- // The same attribute is on IList<T>, IEnumerable<T>, ICollection<T> and IReadOnlyCollection<T>.
- [TypeDependencyAttribute("System.SZArrayHelper")]
- // If we ever implement more interfaces on IReadOnlyList, we should also update RuntimeTypeCache.PopulateInterfaces() in rttype.cs
- public interface IReadOnlyList<out T> : IReadOnlyCollection<T>
- {
- T this[int index] { get; }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/KeyNotFoundException.cs b/src/mscorlib/src/System/Collections/Generic/KeyNotFoundException.cs
deleted file mode 100644
index 1cd18cf808..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/KeyNotFoundException.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*=============================================================================
-**
-**
-**
-**
-**
-** Purpose: Exception class for Hashtable and Dictionary.
-**
-**
-=============================================================================*/
-
-namespace System.Collections.Generic {
-
- using System;
- using System.Runtime.Remoting;
- using System.Runtime.Serialization;
-
- [Serializable]
- public class KeyNotFoundException : SystemException, ISerializable {
-
- public KeyNotFoundException ()
- : base(Environment.GetResourceString("Arg_KeyNotFound")) {
- SetErrorCode(System.__HResults.COR_E_KEYNOTFOUND);
- }
-
- public KeyNotFoundException(String message)
- : base(message) {
- SetErrorCode(System.__HResults.COR_E_KEYNOTFOUND);
- }
-
- public KeyNotFoundException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(System.__HResults.COR_E_KEYNOTFOUND);
- }
-
-
- protected KeyNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs b/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs
deleted file mode 100644
index ba98adad7d..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: KeyValuePair
-**
-**
-**
-**
-** Purpose: Generic key-value pair for dictionary enumerators.
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
-
- using System;
- using System.ComponentModel;
- using System.Text;
-
- // Provides the Create factory method for KeyValuePair<TKey, TValue>.
- public static class KeyValuePair
- {
- // Creates a new KeyValuePair<TKey, TValue> from the given values.
- public static KeyValuePair<TKey, TValue> Create<TKey, TValue>(TKey key, TValue value)
- {
- return new KeyValuePair<TKey, TValue>(key, value);
- }
- }
-
- // A KeyValuePair holds a key and a value from a dictionary.
- // It is used by the IEnumerable<T> implementation for both IDictionary<TKey, TValue>
- // and IReadOnlyDictionary<TKey, TValue>.
- [Serializable]
- public struct KeyValuePair<TKey, TValue> {
- private TKey key;
- private TValue value;
-
- public KeyValuePair(TKey key, TValue value) {
- this.key = key;
- this.value = value;
- }
-
- public TKey Key {
- get { return key; }
- }
-
- public TValue Value {
- get { return value; }
- }
-
- public override string ToString() {
- StringBuilder s = StringBuilderCache.Acquire();
- s.Append('[');
- if( Key != null) {
- s.Append(Key.ToString());
- }
- s.Append(", ");
- if( Value != null) {
- s.Append(Value.ToString());
- }
- s.Append(']');
- return StringBuilderCache.GetStringAndRelease(s);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out TKey key, out TValue value)
- {
- key = Key;
- value = Value;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/List.cs b/src/mscorlib/src/System/Collections/Generic/List.cs
index 362e26599d..67d1668aad 100644
--- a/src/mscorlib/src/System/Collections/Generic/List.cs
+++ b/src/mscorlib/src/System/Collections/Generic/List.cs
@@ -12,15 +12,15 @@
**
**
===========================================================*/
-namespace System.Collections.Generic {
- using System;
- using System.Runtime;
- using System.Runtime.Versioning;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Collections.ObjectModel;
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Collections.ObjectModel;
+using System.Runtime.CompilerServices;
+namespace System.Collections.Generic
+{
// Implements a variable-size List that uses an array of objects to store the
// elements. A List has a capacity, which is the allocated length
// of the internal array. As elements are added to a List, the capacity
@@ -40,22 +40,24 @@ namespace System.Collections.Generic {
private int _version;
[NonSerialized]
private Object _syncRoot;
-
- static readonly T[] _emptyArray = new T[0];
-
+
+ private static readonly T[] _emptyArray = new T[0];
+
// Constructs a List. The list is initially empty and has a capacity
// of zero. Upon adding the first element to the list the capacity is
// increased to _defaultCapacity, and then increased in multiples of two
// as required.
- public List() {
+ public List()
+ {
_items = _emptyArray;
}
-
+
// Constructs a List with a given initial capacity. The list is
// initially empty, but will have room for the given number of elements
// before any reallocations are required.
//
- public List(int capacity) {
+ public List(int capacity)
+ {
if (capacity < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
@@ -64,116 +66,142 @@ namespace System.Collections.Generic {
else
_items = new T[capacity];
}
-
+
// Constructs a List, copying the contents of the given collection. The
// size and capacity of the new list will both be equal to the size of the
// given collection.
//
- public List(IEnumerable<T> collection) {
- if (collection==null)
+ public List(IEnumerable<T> collection)
+ {
+ if (collection == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
Contract.EndContractBlock();
ICollection<T> c = collection as ICollection<T>;
- if( c != null) {
+ if (c != null)
+ {
int count = c.Count;
if (count == 0)
{
_items = _emptyArray;
}
- else {
+ else
+ {
_items = new T[count];
c.CopyTo(_items, 0);
_size = count;
}
- }
- else {
+ }
+ else
+ {
_size = 0;
_items = _emptyArray;
AddEnumerable(collection);
}
}
-
+
// Gets and sets the capacity of this list. The capacity is the size of
// the internal array used to hold items. When set, the internal
// array of the list is reallocated to the given capacity.
//
- public int Capacity {
- get {
+ public int Capacity
+ {
+ get
+ {
Contract.Ensures(Contract.Result<int>() >= 0);
return _items.Length;
}
- set {
- if (value < _size) {
+ set
+ {
+ if (value < _size)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_SmallCapacity);
}
Contract.EndContractBlock();
- if (value != _items.Length) {
- if (value > 0) {
+ if (value != _items.Length)
+ {
+ if (value > 0)
+ {
T[] newItems = new T[value];
- if (_size > 0) {
+ if (_size > 0)
+ {
Array.Copy(_items, 0, newItems, 0, _size);
}
_items = newItems;
}
- else {
+ else
+ {
_items = _emptyArray;
}
}
}
}
-
+
// Read-only property describing how many elements are in the List.
- public int Count {
- get {
+ public int Count
+ {
+ get
+ {
Contract.Ensures(Contract.Result<int>() >= 0);
- return _size;
+ return _size;
}
}
- bool System.Collections.IList.IsFixedSize {
+ bool System.Collections.IList.IsFixedSize
+ {
get { return false; }
}
-
+
// Is this List read-only?
- bool ICollection<T>.IsReadOnly {
+ bool ICollection<T>.IsReadOnly
+ {
get { return false; }
}
- bool System.Collections.IList.IsReadOnly {
+ bool System.Collections.IList.IsReadOnly
+ {
get { return false; }
}
// Is this List synchronized (thread-safe)?
- bool System.Collections.ICollection.IsSynchronized {
+ bool System.Collections.ICollection.IsSynchronized
+ {
get { return false; }
}
-
+
// Synchronization root for this object.
- Object System.Collections.ICollection.SyncRoot {
- get {
- if( _syncRoot == null) {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ Object System.Collections.ICollection.SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
return _syncRoot;
}
}
// Sets or Gets the element at the given index.
//
- public T this[int index] {
- get {
+ public T this[int index]
+ {
+ get
+ {
// Following trick can reduce the range check by one
- if ((uint) index >= (uint)_size) {
+ if ((uint)index >= (uint)_size)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
Contract.EndContractBlock();
- return _items[index];
+ return _items[index];
}
- set {
- if ((uint) index >= (uint)_size) {
+ set
+ {
+ if ((uint)index >= (uint)_size)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
Contract.EndContractBlock();
@@ -182,24 +210,30 @@ namespace System.Collections.Generic {
}
}
- private static bool IsCompatibleObject(object value) {
+ private static bool IsCompatibleObject(object value)
+ {
// Non-null values are fine. Only accept nulls if T is a class or Nullable<U>.
// Note that default(T) is not equal to null for value types except when T is Nullable<U>.
return ((value is T) || (value == null && default(T) == null));
}
- Object System.Collections.IList.this[int index] {
- get {
+ Object System.Collections.IList.this[int index]
+ {
+ get
+ {
return this[index];
}
- set {
+ set
+ {
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(value, ExceptionArgument.value);
- try {
- this[index] = (T)value;
+ try
+ {
+ this[index] = (T)value;
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
}
}
}
@@ -207,22 +241,44 @@ namespace System.Collections.Generic {
// Adds the given object to the end of this list. The size of the list is
// increased by one. If required, the capacity of the list is doubled
// before adding the new element.
- //
- public void Add(T item) {
- if (_size == _items.Length) EnsureCapacity(_size + 1);
- _items[_size++] = item;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Add(T item)
+ {
+ var array = _items;
+ var size = _size;
_version++;
+ if ((uint)size < (uint)array.Length)
+ {
+ _size = size + 1;
+ array[size] = item;
+ }
+ else
+ {
+ AddWithResize(item);
+ }
+ }
+
+ // Non-inline from List.Add to improve its code quality as uncommon path
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private void AddWithResize(T item)
+ {
+ var size = _size;
+ EnsureCapacity(size + 1);
+ _size = size + 1;
+ _items[size] = item;
}
int System.Collections.IList.Add(Object item)
{
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(item, ExceptionArgument.item);
- try {
- Add((T) item);
+ try
+ {
+ Add((T)item);
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(item, typeof(T));
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(item, typeof(T));
}
return Count - 1;
@@ -233,17 +289,19 @@ namespace System.Collections.Generic {
// required, the capacity of the list is increased to twice the previous
// capacity or the new size, whichever is larger.
//
- public void AddRange(IEnumerable<T> collection) {
+ public void AddRange(IEnumerable<T> collection)
+ {
Contract.Ensures(Count >= Contract.OldValue(Count));
InsertRange(_size, collection);
}
- public ReadOnlyCollection<T> AsReadOnly() {
+ public ReadOnlyCollection<T> AsReadOnly()
+ {
Contract.Ensures(Contract.Result<ReadOnlyCollection<T>>() != null);
return new ReadOnlyCollection<T>(this);
}
-
+
// Searches a section of the list for a given element using a binary search
// algorithm. Elements of the list are compared to the search value using
// the given IComparer interface. If comparer is null, elements of
@@ -264,7 +322,8 @@ namespace System.Collections.Generic {
// The method uses the Array.BinarySearch method to perform the
// search.
//
- public int BinarySearch(int index, int count, T item, IComparer<T> comparer) {
+ public int BinarySearch(int index, int count, T item, IComparer<T> comparer)
+ {
if (index < 0)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
if (count < 0)
@@ -276,7 +335,7 @@ namespace System.Collections.Generic {
return Array.BinarySearch<T>(_items, index, count, item, comparer);
}
-
+
public int BinarySearch(T item)
{
Contract.Ensures(Contract.Result<int>() <= Count);
@@ -289,17 +348,27 @@ namespace System.Collections.Generic {
return BinarySearch(0, Count, item, comparer);
}
-
+
// Clears the contents of List.
- public void Clear() {
- if (_size > 0)
+ public void Clear()
+ {
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
- Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
+ int size = _size;
_size = 0;
+ _version++;
+ if (size > 0)
+ {
+ Array.Clear(_items, 0, size); // Clear the elements so that the gc can reclaim the references.
+ }
+ }
+ else
+ {
+ _size = 0;
+ _version++;
}
- _version++;
}
-
+
// Contains returns true if the specified element is in the List.
// It does a linear, O(n) search. Equality is determined by calling
// EqualityComparer<T>.Default.Equals().
@@ -319,21 +388,25 @@ namespace System.Collections.Generic {
bool System.Collections.IList.Contains(Object item)
{
- if(IsCompatibleObject(item)) {
- return Contains((T) item);
+ if (IsCompatibleObject(item))
+ {
+ return Contains((T)item);
}
return false;
}
- public List<TOutput> ConvertAll<TOutput>(Converter<T,TOutput> converter) {
- if( converter == null) {
+ public List<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter)
+ {
+ if (converter == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.converter);
}
Contract.EndContractBlock();
List<TOutput> list = new List<TOutput>(_size);
- for( int i = 0; i< _size; i++) {
+ for (int i = 0; i < _size; i++)
+ {
list._items[i] = converter(_items[i]);
}
list._size = _size;
@@ -343,43 +416,51 @@ namespace System.Collections.Generic {
// Copies this List into array, which must be of a
// compatible array type.
//
- public void CopyTo(T[] array) {
+ public void CopyTo(T[] array)
+ {
CopyTo(array, 0);
}
// Copies this List into array, which must be of a
// compatible array type.
//
- void System.Collections.ICollection.CopyTo(Array array, int arrayIndex) {
- if ((array != null) && (array.Rank != 1)) {
+ void System.Collections.ICollection.CopyTo(Array array, int arrayIndex)
+ {
+ if ((array != null) && (array.Rank != 1))
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
Contract.EndContractBlock();
- try {
+ try
+ {
// Array.Copy will check for NULL.
Array.Copy(_items, 0, array, arrayIndex, _size);
}
- catch(ArrayTypeMismatchException){
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
-
+
// Copies a section of this list to the given array at the given index.
//
// The method uses the Array.Copy method to copy the elements.
//
- public void CopyTo(int index, T[] array, int arrayIndex, int count) {
- if (_size - index < count) {
+ public void CopyTo(int index, T[] array, int arrayIndex, int count)
+ {
+ if (_size - index < count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
}
Contract.EndContractBlock();
-
+
// Delegate rest of error checking to Array.Copy.
Array.Copy(_items, index, array, arrayIndex, count);
}
- public void CopyTo(T[] array, int arrayIndex) {
+ public void CopyTo(T[] array, int arrayIndex)
+ {
// Delegate rest of error checking to Array.Copy.
Array.Copy(_items, 0, array, arrayIndex, _size);
}
@@ -388,9 +469,11 @@ namespace System.Collections.Generic {
// value. If the current capacity of the list is less than min, the
// capacity is increased to twice the current capacity or to min,
// whichever is larger.
- private void EnsureCapacity(int min) {
- if (_items.Length < min) {
- int newCapacity = _items.Length == 0? _defaultCapacity : _items.Length * 2;
+ private void EnsureCapacity(int min)
+ {
+ if (_items.Length < min)
+ {
+ int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Length * 2;
// Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow.
// Note that this check works even when _items.Length overflowed thanks to the (uint) cast
if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength;
@@ -398,62 +481,77 @@ namespace System.Collections.Generic {
Capacity = newCapacity;
}
}
-
- public bool Exists(Predicate<T> match) {
+
+ public bool Exists(Predicate<T> match)
+ {
return FindIndex(match) != -1;
}
- public T Find(Predicate<T> match) {
- if( match == null) {
+ public T Find(Predicate<T> match)
+ {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
- for(int i = 0 ; i < _size; i++) {
- if(match(_items[i])) {
+ for (int i = 0; i < _size; i++)
+ {
+ if (match(_items[i]))
+ {
return _items[i];
}
}
return default(T);
}
-
- public List<T> FindAll(Predicate<T> match) {
- if( match == null) {
+
+ public List<T> FindAll(Predicate<T> match)
+ {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
- List<T> list = new List<T>();
- for(int i = 0 ; i < _size; i++) {
- if(match(_items[i])) {
+ List<T> list = new List<T>();
+ for (int i = 0; i < _size; i++)
+ {
+ if (match(_items[i]))
+ {
list.Add(_items[i]);
}
}
return list;
}
-
- public int FindIndex(Predicate<T> match) {
+
+ public int FindIndex(Predicate<T> match)
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() < Count);
return FindIndex(0, _size, match);
}
-
- public int FindIndex(int startIndex, Predicate<T> match) {
+
+ public int FindIndex(int startIndex, Predicate<T> match)
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() < startIndex + Count);
return FindIndex(startIndex, _size - startIndex, match);
}
-
- public int FindIndex(int startIndex, int count, Predicate<T> match) {
- if( (uint)startIndex > (uint)_size ) {
- ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
+
+ public int FindIndex(int startIndex, int count, Predicate<T> match)
+ {
+ if ((uint)startIndex > (uint)_size)
+ {
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
- if (count < 0 || startIndex > _size - count) {
+ if (count < 0 || startIndex > _size - count)
+ {
ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
- if( match == null) {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.Ensures(Contract.Result<int>() >= -1);
@@ -461,83 +559,103 @@ namespace System.Collections.Generic {
Contract.EndContractBlock();
int endIndex = startIndex + count;
- for( int i = startIndex; i < endIndex; i++) {
- if( match(_items[i])) return i;
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ if (match(_items[i])) return i;
}
return -1;
}
-
- public T FindLast(Predicate<T> match) {
- if( match == null) {
+
+ public T FindLast(Predicate<T> match)
+ {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
- for(int i = _size - 1 ; i >= 0; i--) {
- if(match(_items[i])) {
+ for (int i = _size - 1; i >= 0; i--)
+ {
+ if (match(_items[i]))
+ {
return _items[i];
}
}
return default(T);
}
- public int FindLastIndex(Predicate<T> match) {
+ public int FindLastIndex(Predicate<T> match)
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() < Count);
return FindLastIndex(_size - 1, _size, match);
}
-
- public int FindLastIndex(int startIndex, Predicate<T> match) {
+
+ public int FindLastIndex(int startIndex, Predicate<T> match)
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() <= startIndex);
return FindLastIndex(startIndex, startIndex + 1, match);
}
- public int FindLastIndex(int startIndex, int count, Predicate<T> match) {
- if( match == null) {
+ public int FindLastIndex(int startIndex, int count, Predicate<T> match)
+ {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() <= startIndex);
Contract.EndContractBlock();
- if(_size == 0) {
+ if (_size == 0)
+ {
// Special case for 0 length List
- if( startIndex != -1) {
+ if (startIndex != -1)
+ {
ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
}
- else {
+ else
+ {
// Make sure we're not out of range
- if ( (uint)startIndex >= (uint)_size) {
+ if ((uint)startIndex >= (uint)_size)
+ {
ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
}
-
+
// 2nd have of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0.
- if (count < 0 || startIndex - count + 1 < 0) {
+ if (count < 0 || startIndex - count + 1 < 0)
+ {
ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
-
+
int endIndex = startIndex - count;
- for( int i = startIndex; i > endIndex; i--) {
- if( match(_items[i])) {
+ for (int i = startIndex; i > endIndex; i--)
+ {
+ if (match(_items[i]))
+ {
return i;
}
}
return -1;
}
- public void ForEach(Action<T> action) {
- if( action == null) {
+ public void ForEach(Action<T> action)
+ {
+ if (action == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.action);
}
Contract.EndContractBlock();
int version = _version;
- for(int i = 0 ; i < _size; i++) {
- if (version != _version) {
+ for (int i = 0; i < _size; i++)
+ {
+ if (version != _version)
+ {
break;
}
action(_items[i]);
@@ -552,36 +670,42 @@ namespace System.Collections.Generic {
// while an enumeration is in progress, the MoveNext and
// GetObject methods of the enumerator will throw an exception.
//
- public Enumerator GetEnumerator() {
+ public Enumerator GetEnumerator()
+ {
return new Enumerator(this);
}
- /// <internalonly/>
- IEnumerator<T> IEnumerable<T>.GetEnumerator() {
+ IEnumerator<T> IEnumerable<T>.GetEnumerator()
+ {
return new Enumerator(this);
}
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
return new Enumerator(this);
}
- public List<T> GetRange(int index, int count) {
- if (index < 0) {
+ public List<T> GetRange(int index, int count)
+ {
+ if (index < 0)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (count < 0) {
+ if (count < 0)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
- if (_size - index < count) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
+ if (_size - index < count)
+ {
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
}
Contract.Ensures(Contract.Result<List<T>>() != null);
Contract.EndContractBlock();
List<T> list = new List<T>(count);
- Array.Copy(_items, index, list._items, 0, count);
+ Array.Copy(_items, index, list._items, 0, count);
list._size = count;
return list;
}
@@ -595,7 +719,8 @@ namespace System.Collections.Generic {
// This method uses the Array.IndexOf method to perform the
// search.
//
- public int IndexOf(T item) {
+ public int IndexOf(T item)
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() < Count);
return Array.IndexOf(_items, item, 0, _size);
@@ -603,7 +728,8 @@ namespace System.Collections.Generic {
int System.Collections.IList.IndexOf(Object item)
{
- if(IsCompatibleObject(item)) {
+ if (IsCompatibleObject(item))
+ {
return IndexOf((T)item);
}
return -1;
@@ -618,7 +744,8 @@ namespace System.Collections.Generic {
// This method uses the Array.IndexOf method to perform the
// search.
//
- public int IndexOf(T item, int index) {
+ public int IndexOf(T item, int index)
+ {
if (index > _size)
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
Contract.Ensures(Contract.Result<int>() >= -1);
@@ -636,46 +763,52 @@ namespace System.Collections.Generic {
// This method uses the Array.IndexOf method to perform the
// search.
//
- public int IndexOf(T item, int index, int count) {
+ public int IndexOf(T item, int index, int count)
+ {
if (index > _size)
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
- if (count <0 || index > _size - count) ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
+ if (count < 0 || index > _size - count) ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() < Count);
Contract.EndContractBlock();
return Array.IndexOf(_items, item, index, count);
}
-
+
// Inserts an element into this list at a given index. The size of the list
// is increased by one. If required, the capacity of the list is doubled
// before inserting the new element.
//
- public void Insert(int index, T item) {
+ public void Insert(int index, T item)
+ {
// Note that insertions at the end are legal.
- if ((uint) index > (uint)_size) {
+ if ((uint)index > (uint)_size)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_ListInsert);
}
Contract.EndContractBlock();
if (_size == _items.Length) EnsureCapacity(_size + 1);
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index, _items, index + 1, _size - index);
}
_items[index] = item;
- _size++;
+ _size++;
_version++;
}
-
+
void System.Collections.IList.Insert(int index, Object item)
{
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(item, ExceptionArgument.item);
- try {
- Insert(index, (T) item);
+ try
+ {
+ Insert(index, (T)item);
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(item, typeof(T));
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(item, typeof(T));
}
}
@@ -684,44 +817,55 @@ namespace System.Collections.Generic {
// capacity or the new size, whichever is larger. Ranges may be added
// to the end of the list by setting index to the List's size.
//
- public void InsertRange(int index, IEnumerable<T> collection) {
- if (collection==null) {
+ public void InsertRange(int index, IEnumerable<T> collection)
+ {
+ if (collection == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
-
- if ((uint)index > (uint)_size) {
+
+ if ((uint)index > (uint)_size)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
Contract.EndContractBlock();
ICollection<T> c = collection as ICollection<T>;
- if( c != null ) { // if collection is ICollection<T>
+ if (c != null)
+ { // if collection is ICollection<T>
int count = c.Count;
- if (count > 0) {
+ if (count > 0)
+ {
EnsureCapacity(_size + count);
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index, _items, index + count, _size - index);
}
-
+
// If we're inserting a List into itself, we want to be able to deal with that.
- if (this == c) {
+ if (this == c)
+ {
// Copy first part of _items to insert location
Array.Copy(_items, 0, _items, index, index);
// Copy last part of _items back to inserted location
- Array.Copy(_items, index+count, _items, index*2, _size-index);
+ Array.Copy(_items, index + count, _items, index * 2, _size - index);
}
- else {
+ else
+ {
c.CopyTo(_items, index);
}
_size += count;
- }
+ }
}
- else if (index < _size) {
+ else if (index < _size)
+ {
// We're inserting a lazy enumerable. Call Insert on each of the constituent items.
- using(IEnumerator<T> en = collection.GetEnumerator()) {
- while(en.MoveNext()) {
- Insert(index++, en.Current);
- }
+ using (IEnumerator<T> en = collection.GetEnumerator())
+ {
+ while (en.MoveNext())
+ {
+ Insert(index++, en.Current);
+ }
}
}
else
@@ -729,9 +873,9 @@ namespace System.Collections.Generic {
// We're adding a lazy enumerable because the index is at the end of this list.
AddEnumerable(collection);
}
- _version++;
+ _version++;
}
-
+
// Returns the index of the last occurrence of a given value in a range of
// this list. The list is searched backwards, starting at the end
// and ending at the first element in the list. The elements of the list
@@ -744,10 +888,12 @@ namespace System.Collections.Generic {
{
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() < Count);
- if (_size == 0) { // Special case for empty list
+ if (_size == 0)
+ { // Special case for empty list
return -1;
}
- else {
+ else
+ {
return LastIndexOf(item, _size - 1, _size);
}
}
@@ -780,39 +926,47 @@ namespace System.Collections.Generic {
// This method uses the Array.LastIndexOf method to perform the
// search.
//
- public int LastIndexOf(T item, int index, int count) {
- if ((Count != 0) && (index < 0)) {
+ public int LastIndexOf(T item, int index, int count)
+ {
+ if ((Count != 0) && (index < 0))
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if ((Count !=0) && (count < 0)) {
+ if ((Count != 0) && (count < 0))
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(((Count == 0) && (Contract.Result<int>() == -1)) || ((Count > 0) && (Contract.Result<int>() <= index)));
Contract.EndContractBlock();
- if (_size == 0) { // Special case for empty list
+ if (_size == 0)
+ { // Special case for empty list
return -1;
}
- if (index >= _size) {
+ if (index >= _size)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_BiggerThanCollection);
}
- if (count > index + 1) {
+ if (count > index + 1)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_BiggerThanCollection);
- }
+ }
return Array.LastIndexOf(_items, item, index, count);
}
-
+
// Removes the element at the given index. The size of the list is
// decreased by one.
//
- public bool Remove(T item) {
+ public bool Remove(T item)
+ {
int index = IndexOf(item);
- if (index >= 0) {
+ if (index >= 0)
+ {
RemoveAt(index);
return true;
}
@@ -822,39 +976,48 @@ namespace System.Collections.Generic {
void System.Collections.IList.Remove(Object item)
{
- if(IsCompatibleObject(item)) {
- Remove((T) item);
+ if (IsCompatibleObject(item))
+ {
+ Remove((T)item);
}
}
// This method removes all items which matches the predicate.
// The complexity is O(n).
- public int RemoveAll(Predicate<T> match) {
- if( match == null) {
+ public int RemoveAll(Predicate<T> match)
+ {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.Ensures(Contract.Result<int>() >= 0);
Contract.Ensures(Contract.Result<int>() <= Contract.OldValue(Count));
Contract.EndContractBlock();
-
+
int freeIndex = 0; // the first free slot in items array
// Find the first item which needs to be removed.
- while( freeIndex < _size && !match(_items[freeIndex])) freeIndex++;
- if( freeIndex >= _size) return 0;
-
+ while (freeIndex < _size && !match(_items[freeIndex])) freeIndex++;
+ if (freeIndex >= _size) return 0;
+
int current = freeIndex + 1;
- while( current < _size) {
+ while (current < _size)
+ {
// Find the first item which needs to be kept.
- while( current < _size && match(_items[current])) current++;
+ while (current < _size && match(_items[current])) current++;
- if( current < _size) {
+ if (current < _size)
+ {
// copy item to the free slot.
_items[freeIndex++] = _items[current++];
}
- }
-
- Array.Clear(_items, freeIndex, _size - freeIndex);
+ }
+
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
+ {
+ Array.Clear(_items, freeIndex, _size - freeIndex); // Clear the elements so that the gc can reclaim the references.
+ }
+
int result = _size - freeIndex;
_size = freeIndex;
_version++;
@@ -864,61 +1027,80 @@ namespace System.Collections.Generic {
// Removes the element at the given index. The size of the list is
// decreased by one.
//
- public void RemoveAt(int index) {
- if ((uint)index >= (uint)_size) {
+ public void RemoveAt(int index)
+ {
+ if ((uint)index >= (uint)_size)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
Contract.EndContractBlock();
_size--;
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index + 1, _items, index, _size - index);
}
- _items[_size] = default(T);
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
+ {
+ _items[_size] = default(T);
+ }
_version++;
}
-
+
// Removes a range of elements from this list.
//
- public void RemoveRange(int index, int count) {
- if (index < 0) {
+ public void RemoveRange(int index, int count)
+ {
+ if (index < 0)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (count < 0) {
+ if (count < 0)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
-
+
if (_size - index < count)
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
Contract.EndContractBlock();
-
- if (count > 0) {
+
+ if (count > 0)
+ {
int i = _size;
_size -= count;
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index + count, _items, index, _size - index);
}
- Array.Clear(_items, _size, count);
+
_version++;
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
+ {
+ Array.Clear(_items, _size, count);
+ }
}
}
-
+
// Reverses the elements in this list.
- public void Reverse() {
+ public void Reverse()
+ {
Reverse(0, Count);
}
-
+
// Reverses the elements in a range of this list. Following a call to this
// method, an element in the range given by index and count
// which was previously located at index i will now be located at
// index index + (index + count - i - 1).
//
- public void Reverse(int index, int count) {
- if (index < 0) {
+ public void Reverse(int index, int count)
+ {
+ if (index < 0)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
-
- if (count < 0) {
+
+ if (count < 0)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
@@ -926,12 +1108,13 @@ namespace System.Collections.Generic {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
Contract.EndContractBlock();
- if (count > 1) {
+ if (count > 1)
+ {
Array.Reverse(_items, index, count);
}
_version++;
}
-
+
// Sorts the elements in this list. Uses the default comparer and
// Array.Sort.
public void Sort()
@@ -954,32 +1137,39 @@ namespace System.Collections.Generic {
//
// This method uses the Array.Sort method to sort the elements.
//
- public void Sort(int index, int count, IComparer<T> comparer) {
- if (index < 0) {
+ public void Sort(int index, int count, IComparer<T> comparer)
+ {
+ if (index < 0)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
-
- if (count < 0) {
+
+ if (count < 0)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
-
+
if (_size - index < count)
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
Contract.EndContractBlock();
- if (count > 1) {
+ if (count > 1)
+ {
Array.Sort<T>(_items, index, count, comparer);
}
_version++;
}
- public void Sort(Comparison<T> comparison) {
- if( comparison == null) {
+ public void Sort(Comparison<T> comparison)
+ {
+ if (comparison == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.comparison);
}
Contract.EndContractBlock();
- if (_size > 1) {
+ if (_size > 1)
+ {
ArraySortHelper<T>.Sort(_items, 0, _size, comparison);
}
_version++;
@@ -987,7 +1177,8 @@ namespace System.Collections.Generic {
// ToArray returns an array containing the contents of the List.
// This requires copying the List, which is an O(n) operation.
- public T[] ToArray() {
+ public T[] ToArray()
+ {
Contract.Ensures(Contract.Result<T[]>() != null);
Contract.Ensures(Contract.Result<T[]>().Length == Count);
@@ -1000,7 +1191,7 @@ namespace System.Collections.Generic {
Array.Copy(_items, 0, array, 0, _size);
return array;
}
-
+
// Sets the capacity of this list to the size of the list. This method can
// be used to minimize a list's memory overhead once it is known that no
// new elements will be added to the list. To completely clear a list and
@@ -1010,21 +1201,27 @@ namespace System.Collections.Generic {
// list.Clear();
// list.TrimExcess();
//
- public void TrimExcess() {
- int threshold = (int)(((double)_items.Length) * 0.9);
- if( _size < threshold ) {
- Capacity = _size;
+ public void TrimExcess()
+ {
+ int threshold = (int)(((double)_items.Length) * 0.9);
+ if (_size < threshold)
+ {
+ Capacity = _size;
}
- }
+ }
- public bool TrueForAll(Predicate<T> match) {
- if( match == null) {
+ public bool TrueForAll(Predicate<T> match)
+ {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
- for(int i = 0 ; i < _size; i++) {
- if( !match(_items[i])) {
+ for (int i = 0; i < _size; i++)
+ {
+ if (!match(_items[i]))
+ {
return false;
}
}
@@ -1064,23 +1261,25 @@ namespace System.Collections.Generic {
private int version;
private T current;
- internal Enumerator(List<T> list) {
+ internal Enumerator(List<T> list)
+ {
this.list = list;
index = 0;
version = list._version;
current = default(T);
}
- public void Dispose() {
+ public void Dispose()
+ {
}
- public bool MoveNext() {
-
+ public bool MoveNext()
+ {
List<T> localList = list;
- if (version == localList._version && ((uint)index < (uint)localList._size))
- {
- current = localList._items[index];
+ if (version == localList._version && ((uint)index < (uint)localList._size))
+ {
+ current = localList._items[index];
index++;
return true;
}
@@ -1088,40 +1287,47 @@ namespace System.Collections.Generic {
}
private bool MoveNextRare()
- {
- if (version != list._version) {
+ {
+ if (version != list._version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
index = list._size + 1;
current = default(T);
- return false;
+ return false;
}
- public T Current {
- get {
+ public T Current
+ {
+ get
+ {
return current;
}
}
- Object System.Collections.IEnumerator.Current {
- get {
- if( index == 0 || index == list._size + 1) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ Object System.Collections.IEnumerator.Current
+ {
+ get
+ {
+ if (index == 0 || index == list._size + 1)
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return Current;
}
}
-
- void System.Collections.IEnumerator.Reset() {
- if (version != list._version) {
+
+ void System.Collections.IEnumerator.Reset()
+ {
+ if (version != list._version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
-
+
index = 0;
current = default(T);
}
-
}
}
}
diff --git a/src/mscorlib/src/System/Collections/Hashtable.cs b/src/mscorlib/src/System/Collections/Hashtable.cs
index d1831dd97d..e2fd57ea4d 100644
--- a/src/mscorlib/src/System/Collections/Hashtable.cs
+++ b/src/mscorlib/src/System/Collections/Hashtable.cs
@@ -13,12 +13,13 @@
**
===========================================================*/
-namespace System.Collections {
+namespace System.Collections
+{
using System;
using System.Runtime;
using System.Runtime.Serialization;
using System.Diagnostics;
- using System.Threading;
+ using System.Threading;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Diagnostics.Contracts;
@@ -66,7 +67,8 @@ namespace System.Collections {
[DebuggerTypeProxy(typeof(System.Collections.Hashtable.HashtableDebugView))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
- internal class Hashtable : IDictionary, ISerializable, IDeserializationCallback, ICloneable {
+ internal class Hashtable : IDictionary, ISerializable, IDeserializationCallback, ICloneable
+ {
/*
Implementation Notes:
The generic Dictionary was copied from Hashtable's source - any bug
@@ -121,7 +123,7 @@ namespace System.Collections {
--
*/
-
+
internal const Int32 HashPrime = 101;
private const Int32 InitialSize = 3;
private const String LoadFactorName = "LoadFactor";
@@ -132,31 +134,32 @@ namespace System.Collections {
private const String KeysName = "Keys";
private const String ValuesName = "Values";
private const String KeyComparerName = "KeyComparer";
-
+
// Deleted entries have their key set to buckets
-
+
// The hash table data.
// This cannot be serialised
- private struct bucket {
+ private struct bucket
+ {
public Object key;
public Object val;
public int hash_coll; // Store hash code; sign bit means there was a collision.
}
-
+
private bucket[] buckets;
-
+
// The total number of entries in the hash table.
- private int count;
-
+ private int count;
+
// The total number of collision bits set in the hashtable
private int occupancy;
-
- private int loadsize;
- private float loadFactor;
-
+
+ private int loadsize;
+ private float loadFactor;
+
private volatile int version;
- private volatile bool isWriterInProgress;
-
+ private volatile bool isWriterInProgress;
+
private ICollection keys;
private ICollection values;
@@ -165,15 +168,16 @@ namespace System.Collections {
// Note: this constructor is a bogus constructor that does nothing
// and is for use only with SyncHashtable.
- internal Hashtable( bool trash )
+ internal Hashtable(bool trash)
{
}
// Constructs a new hashtable. The hashtable is created with an initial
// capacity of zero and a load factor of 1.0.
- public Hashtable() : this(0, 1.0f) {
+ public Hashtable() : this(0, 1.0f)
+ {
}
-
+
// Constructs a new hashtable with the given initial capacity and a load
// factor of 1.0. The capacity argument serves as an indication of
// the number of entries the hashtable will contain. When this number (or
@@ -181,9 +185,10 @@ namespace System.Collections {
// eliminate a number of resizing operations that would otherwise be
// performed when elements are added to the hashtable.
//
- public Hashtable(int capacity) : this(capacity, 1.0f) {
+ public Hashtable(int capacity) : this(capacity, 1.0f)
+ {
}
-
+
// Constructs a new hashtable with the given initial capacity and load
// factor. The capacity argument serves as an indication of the
// number of entries the hashtable will contain. When this number (or an
@@ -195,19 +200,20 @@ namespace System.Collections {
// increased memory consumption. A load factor of 1.0 generally provides
// the best balance between speed and size.
//
- public Hashtable(int capacity, float loadFactor) {
+ public Hashtable(int capacity, float loadFactor)
+ {
if (capacity < 0)
- throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_NeedNonNegNum);
if (!(loadFactor >= 0.1f && loadFactor <= 1.0f))
- throw new ArgumentOutOfRangeException(nameof(loadFactor), Environment.GetResourceString("ArgumentOutOfRange_HashtableLoadFactor", .1, 1.0));
+ throw new ArgumentOutOfRangeException(nameof(loadFactor), SR.Format(SR.ArgumentOutOfRange_HashtableLoadFactor, .1, 1.0));
Contract.EndContractBlock();
-
+
// Based on perf work, .72 is the optimal load factor for this table.
this.loadFactor = 0.72f * loadFactor;
double rawsize = capacity / this.loadFactor;
if (rawsize > Int32.MaxValue)
- throw new ArgumentException(Environment.GetResourceString("Arg_HTCapacityOverflow"));
+ throw new ArgumentException(SR.Arg_HTCapacityOverflow);
// Avoid awfully small sizes
int hashsize = (rawsize > InitialSize) ? HashHelpers.GetPrime((int)rawsize) : InitialSize;
@@ -216,18 +222,21 @@ namespace System.Collections {
loadsize = (int)(this.loadFactor * hashsize);
isWriterInProgress = false;
// Based on the current algorithm, loadsize must be less than hashsize.
- Debug.Assert( loadsize < hashsize, "Invalid hashtable loadsize!");
+ Debug.Assert(loadsize < hashsize, "Invalid hashtable loadsize!");
}
-
- public Hashtable(int capacity, float loadFactor, IEqualityComparer equalityComparer) : this(capacity, loadFactor) {
- this._keycomparer = equalityComparer;
+
+ public Hashtable(int capacity, float loadFactor, IEqualityComparer equalityComparer) : this(capacity, loadFactor)
+ {
+ _keycomparer = equalityComparer;
}
- public Hashtable(IEqualityComparer equalityComparer) : this(0, 1.0f, equalityComparer) {
+ public Hashtable(IEqualityComparer equalityComparer) : this(0, 1.0f, equalityComparer)
+ {
}
-
- public Hashtable(int capacity, IEqualityComparer equalityComparer)
- : this(capacity, 1.0f, equalityComparer) {
+
+ public Hashtable(int capacity, IEqualityComparer equalityComparer)
+ : this(capacity, 1.0f, equalityComparer)
+ {
}
// InitHash is basically an implementation of classic DoubleHashing (see http://en.wikipedia.org/wiki/Double_hashing)
@@ -250,11 +259,12 @@ namespace System.Collections {
// The out parameter seed is h1(key), while the out parameter
// incr is h2(key, hashSize). Callers of this function should
// add incr each time through a loop.
- private uint InitHash(Object key, int hashsize, out uint seed, out uint incr) {
+ private uint InitHash(Object key, int hashsize, out uint seed, out uint incr)
+ {
// Hashcode must be positive. Also, we must not use the sign bit, since
// that is used for the collision bit.
- uint hashcode = (uint) GetHash(key) & 0x7FFFFFFF;
- seed = (uint) hashcode;
+ uint hashcode = (uint)GetHash(key) & 0x7FFFFFFF;
+ seed = (uint)hashcode;
// Restriction: incr MUST be between 1 and hashsize - 1, inclusive for
// the modular arithmetic to work correctly. This guarantees you'll
// visit every bucket in the table exactly once within hashsize
@@ -268,64 +278,72 @@ namespace System.Collections {
// ArgumentException is thrown if the key is null or if the key is already
// present in the hashtable.
//
- public virtual void Add(Object key, Object value) {
+ public virtual void Add(Object key, Object value)
+ {
Insert(key, value, true);
}
// Removes all entries from this hashtable.
- public virtual void Clear() {
+ public virtual void Clear()
+ {
Debug.Assert(!isWriterInProgress, "Race condition detected in usages of Hashtable - multiple threads appear to be writing to a Hashtable instance simultaneously! Don't do that - use Hashtable.Synchronized.");
if (count == 0 && occupancy == 0)
return;
isWriterInProgress = true;
- for (int i = 0; i < buckets.Length; i++){
+ for (int i = 0; i < buckets.Length; i++)
+ {
buckets[i].hash_coll = 0;
buckets[i].key = null;
buckets[i].val = null;
}
-
+
count = 0;
occupancy = 0;
- UpdateVersion();
- isWriterInProgress = false;
+ UpdateVersion();
+ isWriterInProgress = false;
}
-
+
// Clone returns a virtually identical copy of this hash table. This does
// a shallow copy - the Objects in the table aren't cloned, only the references
// to those Objects.
public virtual Object Clone()
- {
+ {
bucket[] lbuckets = buckets;
- Hashtable ht = new Hashtable(count,_keycomparer);
+ Hashtable ht = new Hashtable(count, _keycomparer);
ht.version = version;
ht.loadFactor = loadFactor;
ht.count = 0;
int bucket = lbuckets.Length;
- while (bucket > 0) {
+ while (bucket > 0)
+ {
bucket--;
Object keyv = lbuckets[bucket].key;
- if ((keyv!= null) && (keyv != lbuckets)) {
+ if ((keyv != null) && (keyv != lbuckets))
+ {
ht[keyv] = lbuckets[bucket].val;
}
}
return ht;
}
-
+
// Checks if this hashtable contains the given key.
- public virtual bool Contains(Object key) {
+ public virtual bool Contains(Object key)
+ {
return ContainsKey(key);
}
-
+
// Checks if this hashtable contains an entry with the given key. This is
// an O(1) operation.
//
- public virtual bool ContainsKey(Object key) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public virtual bool ContainsKey(Object key)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
@@ -334,68 +352,76 @@ namespace System.Collections {
// Take a snapshot of buckets, in case another thread resizes table
bucket[] lbuckets = buckets;
uint hashcode = InitHash(key, lbuckets.Length, out seed, out incr);
- int ntry = 0;
-
+ int ntry = 0;
+
bucket b;
- int bucketNumber = (int) (seed % (uint)lbuckets.Length);
- do {
+ int bucketNumber = (int)(seed % (uint)lbuckets.Length);
+ do
+ {
b = lbuckets[bucketNumber];
- if (b.key == null) {
+ if (b.key == null)
+ {
return false;
}
- if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
- KeyEquals (b.key, key))
+ if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
+ KeyEquals(b.key, key))
return true;
- bucketNumber = (int) (((long)bucketNumber + incr)% (uint)lbuckets.Length);
+ bucketNumber = (int)(((long)bucketNumber + incr) % (uint)lbuckets.Length);
} while (b.hash_coll < 0 && ++ntry < lbuckets.Length);
return false;
}
-
+
// Copies the keys of this hashtable to a given array starting at a given
// index. This method is used by the implementation of the CopyTo method in
// the KeyCollection class.
- private void CopyKeys(Array array, int arrayIndex) {
+ private void CopyKeys(Array array, int arrayIndex)
+ {
Contract.Requires(array != null);
Contract.Requires(array.Rank == 1);
bucket[] lbuckets = buckets;
- for (int i = lbuckets.Length; --i >= 0;) {
+ for (int i = lbuckets.Length; --i >= 0;)
+ {
Object keyv = lbuckets[i].key;
- if ((keyv != null) && (keyv != buckets)){
+ if ((keyv != null) && (keyv != buckets))
+ {
array.SetValue(keyv, arrayIndex++);
}
- }
+ }
}
// Copies the keys of this hashtable to a given array starting at a given
// index. This method is used by the implementation of the CopyTo method in
// the KeyCollection class.
- private void CopyEntries(Array array, int arrayIndex) {
+ private void CopyEntries(Array array, int arrayIndex)
+ {
Contract.Requires(array != null);
Contract.Requires(array.Rank == 1);
bucket[] lbuckets = buckets;
- for (int i = lbuckets.Length; --i >= 0;) {
+ for (int i = lbuckets.Length; --i >= 0;)
+ {
Object keyv = lbuckets[i].key;
- if ((keyv != null) && (keyv != buckets)){
- DictionaryEntry entry = new DictionaryEntry(keyv,lbuckets[i].val);
+ if ((keyv != null) && (keyv != buckets))
+ {
+ DictionaryEntry entry = new DictionaryEntry(keyv, lbuckets[i].val);
array.SetValue(entry, arrayIndex++);
}
}
}
-
+
// Copies the values in this hash table to an array at
// a given index. Note that this only copies values, and not keys.
public virtual void CopyTo(Array array, int arrayIndex)
{
if (array == null)
- throw new ArgumentNullException(nameof(array), Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(nameof(array), SR.ArgumentNull_Array);
if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
- if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
+ if (arrayIndex < 0)
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex), SR.ArgumentOutOfRange_NeedNonNegNum);
if (array.Length - arrayIndex < Count)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
+ throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
Contract.EndContractBlock();
CopyEntries(array, arrayIndex);
}
@@ -404,40 +430,46 @@ namespace System.Collections {
// Copies the values of this hashtable to a given array starting at a given
// index. This method is used by the implementation of the CopyTo method in
// the ValueCollection class.
- private void CopyValues(Array array, int arrayIndex) {
+ private void CopyValues(Array array, int arrayIndex)
+ {
Contract.Requires(array != null);
Contract.Requires(array.Rank == 1);
bucket[] lbuckets = buckets;
- for (int i = lbuckets.Length; --i >= 0;) {
+ for (int i = lbuckets.Length; --i >= 0;)
+ {
Object keyv = lbuckets[i].key;
- if ((keyv != null) && (keyv != buckets)){
+ if ((keyv != null) && (keyv != buckets))
+ {
array.SetValue(lbuckets[i].val, arrayIndex++);
}
}
}
-
+
// Returns the value associated with the given key. If an entry with the
// given key is not found, the returned value is null.
//
- public virtual Object this[Object key] {
- get {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public virtual Object this[Object key]
+ {
+ get
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
uint seed;
uint incr;
-
+
// Take a snapshot of buckets, in case another thread does a resize
bucket[] lbuckets = buckets;
uint hashcode = InitHash(key, lbuckets.Length, out seed, out incr);
- int ntry = 0;
-
+ int ntry = 0;
+
bucket b;
- int bucketNumber = (int) (seed % (uint)lbuckets.Length);
+ int bucketNumber = (int)(seed % (uint)lbuckets.Length);
do
{
int currentversion;
@@ -459,35 +491,39 @@ namespace System.Collections {
// we will see the 'isWriterProgress' flag to be true or 'version' is changed in the reader.
//
int spinCount = 0;
- do {
+ do
+ {
// this is violate read, following memory accesses can not be moved ahead of it.
currentversion = version;
- b = lbuckets[bucketNumber];
+ b = lbuckets[bucketNumber];
// The contention between reader and writer shouldn't happen frequently.
// But just in case this will burn CPU, yield the control of CPU if we spinned a few times.
// 8 is just a random number I pick.
- if( (++spinCount) % 8 == 0 ) {
+ if ((++spinCount) % 8 == 0)
+ {
Thread.Sleep(1); // 1 means we are yeilding control to all threads, including low-priority ones.
}
- } while ( isWriterInProgress || (currentversion != version) );
+ } while (isWriterInProgress || (currentversion != version));
- if (b.key == null) {
+ if (b.key == null)
+ {
return null;
}
- if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
- KeyEquals (b.key, key))
+ if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
+ KeyEquals(b.key, key))
return b.val;
- bucketNumber = (int) (((long)bucketNumber + incr)% (uint)lbuckets.Length);
+ bucketNumber = (int)(((long)bucketNumber + incr) % (uint)lbuckets.Length);
} while (b.hash_coll < 0 && ++ntry < lbuckets.Length);
return null;
}
- set {
+ set
+ {
Insert(key, value, false);
}
}
-
+
// Increases the bucket count of this hashtable. This method is called from
// the Insert method when the actual load factor of the hashtable reaches
// the upper limit specified when the hashtable was constructed. The number
@@ -495,27 +531,30 @@ namespace System.Collections {
// that is larger than twice the current number of buckets, and the entries
// in the hashtable are redistributed into the new buckets using the cached
// hashcodes.
- private void expand() {
+ private void expand()
+ {
int rawsize = HashHelpers.ExpandPrime(buckets.Length);
rehash(rawsize, false);
}
// We occationally need to rehash the table to clean up the collision bits.
- private void rehash() {
- rehash( buckets.Length, false );
+ private void rehash()
+ {
+ rehash(buckets.Length, false);
}
- private void UpdateVersion() {
+ private void UpdateVersion()
+ {
// Version might become negative when version is Int32.MaxValue, but the oddity will be still be correct.
// So we don't need to special case this.
version++;
}
- private void rehash( int newsize, bool forceNewHashCode ) {
-
+ private void rehash(int newsize, bool forceNewHashCode)
+ {
// reset occupancy
- occupancy=0;
-
+ occupancy = 0;
+
// Don't replace any internal state until we've finished adding to the
// new bucket[]. This serves two purposes:
// 1) Allow concurrent readers to see valid hashtable contents
@@ -523,12 +562,14 @@ namespace System.Collections {
// 2) Protect against an OutOfMemoryException while allocating this
// new bucket[].
bucket[] newBuckets = new bucket[newsize];
-
+
// rehash table into new buckets
int nb;
- for (nb = 0; nb < buckets.Length; nb++){
+ for (nb = 0; nb < buckets.Length; nb++)
+ {
bucket oldb = buckets[nb];
- if ((oldb.key != null) && (oldb.key != buckets)) {
+ if ((oldb.key != null) && (oldb.key != buckets))
+ {
int hashcode = ((forceNewHashCode ? GetHash(oldb.key) : oldb.hash_coll) & 0x7FFFFFFF);
putEntry(newBuckets, oldb.key, oldb.val, hashcode);
}
@@ -551,7 +592,8 @@ namespace System.Collections {
// in progress, the MoveNext and Current methods of the
// enumerator will throw an exception.
//
- IEnumerator IEnumerable.GetEnumerator() {
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return new HashtableEnumerator(this, HashtableEnumerator.DictEntry);
}
@@ -560,10 +602,11 @@ namespace System.Collections {
// in progress, the MoveNext and Current methods of the
// enumerator will throw an exception.
//
- public virtual IDictionaryEnumerator GetEnumerator() {
+ public virtual IDictionaryEnumerator GetEnumerator()
+ {
return new HashtableEnumerator(this, HashtableEnumerator.DictEntry);
}
-
+
// Internal method to get the hash code for an Object. This will call
// GetHashCode() on each object if you haven't provided an IHashCodeProvider
// instance. Otherwise, it calls hcp.GetHashCode(obj).
@@ -575,16 +618,19 @@ namespace System.Collections {
}
// Is this Hashtable read-only?
- public virtual bool IsReadOnly {
+ public virtual bool IsReadOnly
+ {
get { return false; }
}
- public virtual bool IsFixedSize {
+ public virtual bool IsFixedSize
+ {
get { return false; }
}
// Is this Hashtable synchronized? See SyncRoot property
- public virtual bool IsSynchronized {
+ public virtual bool IsSynchronized
+ {
get { return false; }
}
@@ -595,11 +641,12 @@ namespace System.Collections {
protected virtual bool KeyEquals(Object item, Object key)
{
Debug.Assert(key != null, "key can't be null here!");
- if( Object.ReferenceEquals(buckets, item)) {
+ if (Object.ReferenceEquals(buckets, item))
+ {
return false;
}
- if (Object.ReferenceEquals(item,key))
+ if (Object.ReferenceEquals(item, key))
return true;
if (_keycomparer != null)
@@ -616,13 +663,15 @@ namespace System.Collections {
// to the hash table are reflected in this collection. It is not
// a static copy of all the keys in the hash table.
//
- public virtual ICollection Keys {
- get {
+ public virtual ICollection Keys
+ {
+ get
+ {
if (keys == null) keys = new KeyCollection(this);
- return keys;
+ return keys;
}
}
-
+
// Returns a collection representing the values of this hashtable. The
// order in which the returned collection represents the values is
// unspecified, but it is guaranteed to be the same order in which a
@@ -633,39 +682,45 @@ namespace System.Collections {
// to the hash table are reflected in this collection. It is not
// a static copy of all the keys in the hash table.
//
- public virtual ICollection Values {
- get {
+ public virtual ICollection Values
+ {
+ get
+ {
if (values == null) values = new ValueCollection(this);
- return values;
+ return values;
}
}
-
+
// Inserts an entry into this hashtable. This method is called from the Set
// and Add methods. If the add parameter is true and the given key already
// exists in the hashtable, an exception is thrown.
- private void Insert (Object key, Object nvalue, bool add) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ private void Insert(Object key, Object nvalue, bool add)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
- if (count >= loadsize) {
+ if (count >= loadsize)
+ {
expand();
}
- else if(occupancy > loadsize && count > 100) {
+ else if (occupancy > loadsize && count > 100)
+ {
rehash();
}
-
+
uint seed;
uint incr;
// Assume we only have one thread writing concurrently. Modify
// buckets to contain new data, as long as we insert in the right order.
uint hashcode = InitHash(key, buckets.Length, out seed, out incr);
- int ntry = 0;
+ int ntry = 0;
int emptySlotNumber = -1; // We use the empty slot number to cache the first empty slot. We chose to reuse slots
// create by remove that have the collision bit set over using up new slots.
- int bucketNumber = (int) (seed % (uint)buckets.Length);
- do {
-
+ int bucketNumber = (int)(seed % (uint)buckets.Length);
+ do
+ {
// Set emptySlot number to current bucket if it is the first available bucket that we have seen
// that once contained an entry and also has had a collision.
// We need to search this entire collision chain because we have to ensure that there are no
@@ -676,9 +731,9 @@ namespace System.Collections {
// Insert the key/value pair into this bucket if this bucket is empty and has never contained an entry
// OR
// This bucket once contained an entry but there has never been a collision
- if ((buckets[bucketNumber].key == null) ||
- (buckets[bucketNumber].key == buckets && ((buckets[bucketNumber].hash_coll & unchecked(0x80000000))==0))) {
-
+ if ((buckets[bucketNumber].key == null) ||
+ (buckets[bucketNumber].key == buckets && ((buckets[bucketNumber].hash_coll & unchecked(0x80000000)) == 0)))
+ {
// If we have found an available bucket that has never had a collision, but we've seen an available
// bucket in the past that has the collision bit set, use the previous bucket instead
if (emptySlotNumber != -1) // Reuse slot
@@ -688,11 +743,11 @@ namespace System.Collections {
// code until the value & key are set appropriately.
isWriterInProgress = true;
buckets[bucketNumber].val = nvalue;
- buckets[bucketNumber].key = key;
- buckets[bucketNumber].hash_coll |= (int) hashcode;
+ buckets[bucketNumber].key = key;
+ buckets[bucketNumber].hash_coll |= (int)hashcode;
count++;
UpdateVersion();
- isWriterInProgress = false;
+ isWriterInProgress = false;
return;
}
@@ -700,29 +755,33 @@ namespace System.Collections {
// The current bucket is in use
// OR
// it is available, but has had the collision bit set and we have already found an available bucket
- if (((buckets[bucketNumber].hash_coll & 0x7FFFFFFF) == hashcode) &&
- KeyEquals (buckets[bucketNumber].key, key)) {
- if (add) {
- throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate__", buckets[bucketNumber].key, key));
+ if (((buckets[bucketNumber].hash_coll & 0x7FFFFFFF) == hashcode) &&
+ KeyEquals(buckets[bucketNumber].key, key))
+ {
+ if (add)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_AddingDuplicate__, buckets[bucketNumber].key, key));
}
isWriterInProgress = true;
buckets[bucketNumber].val = nvalue;
UpdateVersion();
- isWriterInProgress = false;
+ isWriterInProgress = false;
return;
}
// The current bucket is full, and we have therefore collided. We need to set the collision bit
// UNLESS
// we have remembered an available slot previously.
- if (emptySlotNumber == -1) {// We don't need to set the collision bit here since we already have an empty slot
- if( buckets[bucketNumber].hash_coll >= 0 ) {
+ if (emptySlotNumber == -1)
+ {// We don't need to set the collision bit here since we already have an empty slot
+ if (buckets[bucketNumber].hash_coll >= 0)
+ {
buckets[bucketNumber].hash_coll |= unchecked((int)0x80000000);
occupancy++;
}
}
- bucketNumber = (int) (((long)bucketNumber + incr)% (uint)buckets.Length);
+ bucketNumber = (int)(((long)bucketNumber + incr) % (uint)buckets.Length);
} while (++ntry < buckets.Length);
// This code is here if and only if there were no buckets without a collision bit set in the entire table
@@ -732,11 +791,11 @@ namespace System.Collections {
// code until the value & key are set appropriately.
isWriterInProgress = true;
buckets[emptySlotNumber].val = nvalue;
- buckets[emptySlotNumber].key = key;
- buckets[emptySlotNumber].hash_coll |= (int) hashcode;
+ buckets[emptySlotNumber].key = key;
+ buckets[emptySlotNumber].hash_coll |= (int)hashcode;
count++;
- UpdateVersion();
- isWriterInProgress = false;
+ UpdateVersion();
+ isWriterInProgress = false;
return;
}
@@ -745,40 +804,44 @@ namespace System.Collections {
// Then verify that our double hash function (h2, described at top of file)
// meets the requirements described above. You should never see this assert.
Debug.Assert(false, "hash table insert failed! Load factor too high, or our double hashing function is incorrect.");
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HashInsertFailed"));
+ throw new InvalidOperationException(SR.InvalidOperation_HashInsertFailed);
}
-
- private void putEntry (bucket[] newBuckets, Object key, Object nvalue, int hashcode)
+
+ private void putEntry(bucket[] newBuckets, Object key, Object nvalue, int hashcode)
{
Debug.Assert(hashcode >= 0, "hashcode >= 0"); // make sure collision bit (sign bit) wasn't set.
- uint seed = (uint) hashcode;
+ uint seed = (uint)hashcode;
uint incr = (uint)(1 + ((seed * HashPrime) % ((uint)newBuckets.Length - 1)));
- int bucketNumber = (int) (seed % (uint)newBuckets.Length);
- do {
-
- if ((newBuckets[bucketNumber].key == null) || (newBuckets[bucketNumber].key == buckets)) {
+ int bucketNumber = (int)(seed % (uint)newBuckets.Length);
+ do
+ {
+ if ((newBuckets[bucketNumber].key == null) || (newBuckets[bucketNumber].key == buckets))
+ {
newBuckets[bucketNumber].val = nvalue;
newBuckets[bucketNumber].key = key;
newBuckets[bucketNumber].hash_coll |= hashcode;
return;
}
-
- if( newBuckets[bucketNumber].hash_coll >= 0 ) {
- newBuckets[bucketNumber].hash_coll |= unchecked((int)0x80000000);
+
+ if (newBuckets[bucketNumber].hash_coll >= 0)
+ {
+ newBuckets[bucketNumber].hash_coll |= unchecked((int)0x80000000);
occupancy++;
}
- bucketNumber = (int) (((long)bucketNumber + incr)% (uint)newBuckets.Length);
+ bucketNumber = (int)(((long)bucketNumber + incr) % (uint)newBuckets.Length);
} while (true);
}
-
+
// Removes an entry from this hashtable. If an entry with the specified
// key exists in the hashtable, it is removed. An ArgumentException is
// thrown if the key is null.
//
- public virtual void Remove(Object key) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public virtual void Remove(Object key)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
Debug.Assert(!isWriterInProgress, "Race condition detected in usages of Hashtable - multiple threads appear to be writing to a Hashtable instance simultaneously! Don't do that - use Hashtable.Synchronized.");
@@ -788,124 +851,135 @@ namespace System.Collections {
// Assuming only one concurrent writer, write directly into buckets.
uint hashcode = InitHash(key, buckets.Length, out seed, out incr);
int ntry = 0;
-
+
bucket b;
- int bn = (int) (seed % (uint)buckets.Length); // bucketNumber
- do {
+ int bn = (int)(seed % (uint)buckets.Length); // bucketNumber
+ do
+ {
b = buckets[bn];
- if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
- KeyEquals (b.key, key)) {
+ if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
+ KeyEquals(b.key, key))
+ {
isWriterInProgress = true;
// Clear hash_coll field, then key, then value
buckets[bn].hash_coll &= unchecked((int)0x80000000);
- if (buckets[bn].hash_coll != 0) {
+ if (buckets[bn].hash_coll != 0)
+ {
buckets[bn].key = buckets;
- }
- else {
+ }
+ else
+ {
buckets[bn].key = null;
}
buckets[bn].val = null; // Free object references sooner & simplify ContainsValue.
count--;
UpdateVersion();
- isWriterInProgress = false;
+ isWriterInProgress = false;
return;
}
- bn = (int) (((long)bn + incr)% (uint)buckets.Length);
+ bn = (int)(((long)bn + incr) % (uint)buckets.Length);
} while (b.hash_coll < 0 && ++ntry < buckets.Length);
- //throw new ArgumentException(Environment.GetResourceString("Arg_RemoveArgNotFound"));
+ //throw new ArgumentException(SR.Arg_RemoveArgNotFound);
}
-
+
// Returns the object to synchronize on for this hash table.
- public virtual Object SyncRoot {
- get {
- if( _syncRoot == null) {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ public virtual Object SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
- return _syncRoot;
+ return _syncRoot;
}
}
-
+
// Returns the number of associations in this hashtable.
//
- public virtual int Count {
+ public virtual int Count
+ {
get { return count; }
}
-
+
// Returns a thread-safe wrapper for a Hashtable.
//
- public static Hashtable Synchronized(Hashtable table) {
- if (table==null)
+ public static Hashtable Synchronized(Hashtable table)
+ {
+ if (table == null)
throw new ArgumentNullException(nameof(table));
Contract.EndContractBlock();
return new SyncHashtable(table);
}
-
+
//
// The ISerializable Implementation
//
- public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+ public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
// This is imperfect - it only works well if all other writes are
// also using our synchronized wrapper. But it's still a good idea.
- lock (SyncRoot) {
+ lock (SyncRoot)
+ {
// This method hasn't been fully tweaked to be safe for a concurrent writer.
int oldVersion = version;
- info.AddValue(LoadFactorName, loadFactor);
- info.AddValue(VersionName, version);
-
- //
- // We need to maintain serialization compatibility with Everett and RTM.
- // If the comparer is null or a compatible comparer, serialize Hashtable
- // in a format that can be deserialized on Everett and RTM.
- //
- // Also, if the Hashtable is using randomized hashing, serialize the old
- // view of the _keycomparer so perevious frameworks don't see the new types
+ info.AddValue(LoadFactorName, loadFactor);
+ info.AddValue(VersionName, version);
+
+ //
+ // We need to maintain serialization compatibility with Everett and RTM.
+ // If the comparer is null or a compatible comparer, serialize Hashtable
+ // in a format that can be deserialized on Everett and RTM.
+ //
#pragma warning disable 618
-#if FEATURE_RANDOMIZED_STRING_HASHING
- IEqualityComparer keyComparerForSerilization = (IEqualityComparer) HashHelpers.GetEqualityComparerForSerialization(_keycomparer);
-#else
- IEqualityComparer keyComparerForSerilization = _keycomparer;
-#endif
+ IEqualityComparer keyComparerForSerilization = _keycomparer;
- if( keyComparerForSerilization == null) {
- info.AddValue(ComparerName, null,typeof(IComparer));
- info.AddValue(HashCodeProviderName, null, typeof(IHashCodeProvider));
- }
- else if(keyComparerForSerilization is CompatibleComparer) {
- CompatibleComparer c = keyComparerForSerilization as CompatibleComparer;
- info.AddValue(ComparerName, c.Comparer, typeof(IComparer));
- info.AddValue(HashCodeProviderName, c.HashCodeProvider, typeof(IHashCodeProvider));
- }
- else {
- info.AddValue(KeyComparerName, keyComparerForSerilization, typeof(IEqualityComparer));
- }
+ if (keyComparerForSerilization == null)
+ {
+ info.AddValue(ComparerName, null, typeof(IComparer));
+ info.AddValue(HashCodeProviderName, null, typeof(IHashCodeProvider));
+ }
+ else if (keyComparerForSerilization is CompatibleComparer)
+ {
+ CompatibleComparer c = keyComparerForSerilization as CompatibleComparer;
+ info.AddValue(ComparerName, c.Comparer, typeof(IComparer));
+ info.AddValue(HashCodeProviderName, c.HashCodeProvider, typeof(IHashCodeProvider));
+ }
+ else
+ {
+ info.AddValue(KeyComparerName, keyComparerForSerilization, typeof(IEqualityComparer));
+ }
#pragma warning restore 618
- info.AddValue(HashSizeName, buckets.Length); //This is the length of the bucket array.
- Object [] serKeys = new Object[count];
- Object [] serValues = new Object[count];
- CopyKeys(serKeys, 0);
- CopyValues(serValues,0);
- info.AddValue(KeysName, serKeys, typeof(Object[]));
- info.AddValue(ValuesName, serValues, typeof(Object[]));
+ info.AddValue(HashSizeName, buckets.Length); //This is the length of the bucket array.
+ Object[] serKeys = new Object[count];
+ Object[] serValues = new Object[count];
+ CopyKeys(serKeys, 0);
+ CopyValues(serValues, 0);
+ info.AddValue(KeysName, serKeys, typeof(Object[]));
+ info.AddValue(ValuesName, serValues, typeof(Object[]));
// Explicitly check to see if anyone changed the Hashtable while we
// were serializing it. That's a race condition in their code.
if (version != oldVersion)
- throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
- }
+ throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
+ }
}
-
+
//
// DeserializationEvent Listener
//
- public virtual void OnDeserialization(Object sender) {
- if (buckets!=null) {
+ public virtual void OnDeserialization(Object sender)
+ {
+ if (buckets != null)
+ {
// Somebody had a dependency on this hashtable and fixed us up before the ObjectManager got to it.
return;
}
@@ -913,8 +987,9 @@ namespace System.Collections {
SerializationInfo siInfo;
HashHelpers.SerializationInfoTable.TryGetValue(this, out siInfo);
- if (siInfo==null) {
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidOnDeser"));
+ if (siInfo == null)
+ {
+ throw new SerializationException(SR.Serialization_InvalidOnDeser);
}
int hashsize = 0;
@@ -924,14 +999,14 @@ namespace System.Collections {
IHashCodeProvider hcp = null;
#pragma warning restore 618
- Object [] serKeys = null;
- Object [] serValues = null;
+ Object[] serKeys = null;
+ Object[] serValues = null;
SerializationInfoEnumerator enumerator = siInfo.GetEnumerator();
- while( enumerator.MoveNext())
+ while (enumerator.MoveNext())
{
- switch( enumerator.Name)
+ switch (enumerator.Name)
{
case LoadFactorName:
loadFactor = siInfo.GetSingle(LoadFactorName);
@@ -939,7 +1014,7 @@ namespace System.Collections {
case HashSizeName:
hashsize = siInfo.GetInt32(HashSizeName);
break;
- case KeyComparerName:
+ case KeyComparerName:
_keycomparer = (IEqualityComparer)siInfo.GetValue(KeyComparerName, typeof(IEqualityComparer));
break;
case ComparerName:
@@ -959,129 +1034,148 @@ namespace System.Collections {
}
}
- loadsize = (int)(loadFactor*hashsize);
+ loadsize = (int)(loadFactor * hashsize);
// V1 object doesn't has _keycomparer field.
- if ( (_keycomparer == null) && ( (c != null) || (hcp != null) ) ){
- _keycomparer = new CompatibleComparer(c,hcp);
+ if ((_keycomparer == null) && ((c != null) || (hcp != null)))
+ {
+ _keycomparer = new CompatibleComparer(c, hcp);
}
buckets = new bucket[hashsize];
-
- if (serKeys==null) {
- throw new SerializationException(Environment.GetResourceString("Serialization_MissingKeys"));
+
+ if (serKeys == null)
+ {
+ throw new SerializationException(SR.Serialization_MissingKeys);
}
- if (serValues==null) {
- throw new SerializationException(Environment.GetResourceString("Serialization_MissingValues"));
+ if (serValues == null)
+ {
+ throw new SerializationException(SR.Serialization_MissingValues);
}
- if (serKeys.Length!=serValues.Length) {
- throw new SerializationException(Environment.GetResourceString("Serialization_KeyValueDifferentSizes"));
+ if (serKeys.Length != serValues.Length)
+ {
+ throw new SerializationException(SR.Serialization_KeyValueDifferentSizes);
}
- for (int i=0; i<serKeys.Length; i++) {
- if (serKeys[i]==null) {
- throw new SerializationException(Environment.GetResourceString("Serialization_NullKey"));
+ for (int i = 0; i < serKeys.Length; i++)
+ {
+ if (serKeys[i] == null)
+ {
+ throw new SerializationException(SR.Serialization_NullKey);
}
Insert(serKeys[i], serValues[i], true);
}
-
+
version = siInfo.GetInt32(VersionName);
-
+
HashHelpers.SerializationInfoTable.Remove(this);
}
-
-
+
+
// Implements a Collection for the keys of a hashtable. An instance of this
// class is created by the GetKeys method of a hashtable.
[Serializable]
private class KeyCollection : ICollection
{
private Hashtable _hashtable;
-
- internal KeyCollection(Hashtable hashtable) {
+
+ internal KeyCollection(Hashtable hashtable)
+ {
_hashtable = hashtable;
}
-
- public virtual void CopyTo(Array array, int arrayIndex) {
- if (array==null)
+
+ public virtual void CopyTo(Array array, int arrayIndex)
+ {
+ if (array == null)
throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
- if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
+ if (arrayIndex < 0)
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
if (array.Length - arrayIndex < _hashtable.count)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
+ throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
_hashtable.CopyKeys(array, arrayIndex);
}
-
- public virtual IEnumerator GetEnumerator() {
+
+ public virtual IEnumerator GetEnumerator()
+ {
return new HashtableEnumerator(_hashtable, HashtableEnumerator.Keys);
}
-
- public virtual bool IsSynchronized {
+
+ public virtual bool IsSynchronized
+ {
get { return _hashtable.IsSynchronized; }
}
- public virtual Object SyncRoot {
+ public virtual Object SyncRoot
+ {
get { return _hashtable.SyncRoot; }
}
- public virtual int Count {
+ public virtual int Count
+ {
get { return _hashtable.count; }
}
}
-
+
// Implements a Collection for the values of a hashtable. An instance of
// this class is created by the GetValues method of a hashtable.
[Serializable]
private class ValueCollection : ICollection
{
private Hashtable _hashtable;
-
- internal ValueCollection(Hashtable hashtable) {
+
+ internal ValueCollection(Hashtable hashtable)
+ {
_hashtable = hashtable;
}
-
- public virtual void CopyTo(Array array, int arrayIndex) {
- if (array==null)
+
+ public virtual void CopyTo(Array array, int arrayIndex)
+ {
+ if (array == null)
throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
- if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
+ if (arrayIndex < 0)
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
if (array.Length - arrayIndex < _hashtable.count)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
+ throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
_hashtable.CopyValues(array, arrayIndex);
}
-
- public virtual IEnumerator GetEnumerator() {
+
+ public virtual IEnumerator GetEnumerator()
+ {
return new HashtableEnumerator(_hashtable, HashtableEnumerator.Values);
}
-
- public virtual bool IsSynchronized {
+
+ public virtual bool IsSynchronized
+ {
get { return _hashtable.IsSynchronized; }
}
- public virtual Object SyncRoot {
+ public virtual Object SyncRoot
+ {
get { return _hashtable.SyncRoot; }
}
- public virtual int Count {
+ public virtual int Count
+ {
get { return _hashtable.count; }
}
}
-
+
// Synchronized wrapper for hashtable
[Serializable]
private class SyncHashtable : Hashtable, IEnumerable
{
protected Hashtable _table;
-
- internal SyncHashtable(Hashtable table) : base(false) {
+
+ internal SyncHashtable(Hashtable table) : base(false)
+ {
_table = table;
}
-
+
/*================================GetObjectData=================================
**Action: Return a serialization info containing a reference to _table. We need
@@ -1093,115 +1187,148 @@ namespace System.Collections {
** context -- the StreamingContext for the current serialization (ignored)
**Exceptions: ArgumentNullException if info is null.
==============================================================================*/
- public override void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
// Our serialization code hasn't been fully tweaked to be safe
// for a concurrent writer.
- lock (_table.SyncRoot) {
- info.AddValue("ParentTable", _table, typeof(Hashtable));
- }
+ lock (_table.SyncRoot)
+ {
+ info.AddValue("ParentTable", _table, typeof(Hashtable));
+ }
}
- public override int Count {
+ public override int Count
+ {
get { return _table.Count; }
}
-
- public override bool IsReadOnly {
+
+ public override bool IsReadOnly
+ {
get { return _table.IsReadOnly; }
}
- public override bool IsFixedSize {
+ public override bool IsFixedSize
+ {
get { return _table.IsFixedSize; }
}
-
- public override bool IsSynchronized {
+
+ public override bool IsSynchronized
+ {
get { return true; }
}
- public override Object this[Object key] {
- get {
- return _table[key];
+ public override Object this[Object key]
+ {
+ get
+ {
+ return _table[key];
}
- set {
- lock(_table.SyncRoot) {
+ set
+ {
+ lock (_table.SyncRoot)
+ {
_table[key] = value;
}
}
}
-
- public override Object SyncRoot {
+
+ public override Object SyncRoot
+ {
get { return _table.SyncRoot; }
}
-
- public override void Add(Object key, Object value) {
- lock(_table.SyncRoot) {
+
+ public override void Add(Object key, Object value)
+ {
+ lock (_table.SyncRoot)
+ {
_table.Add(key, value);
}
}
-
- public override void Clear() {
- lock(_table.SyncRoot) {
+
+ public override void Clear()
+ {
+ lock (_table.SyncRoot)
+ {
_table.Clear();
}
}
-
- public override bool Contains(Object key) {
+
+ public override bool Contains(Object key)
+ {
return _table.Contains(key);
}
-
- public override bool ContainsKey(Object key) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+
+ public override bool ContainsKey(Object key)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
return _table.ContainsKey(key);
}
-
- public override void CopyTo(Array array, int arrayIndex) {
- lock (_table.SyncRoot) {
+
+ public override void CopyTo(Array array, int arrayIndex)
+ {
+ lock (_table.SyncRoot)
+ {
_table.CopyTo(array, arrayIndex);
}
}
- public override Object Clone() {
- lock (_table.SyncRoot) {
+ public override Object Clone()
+ {
+ lock (_table.SyncRoot)
+ {
return Hashtable.Synchronized((Hashtable)_table.Clone());
}
}
-
- IEnumerator IEnumerable.GetEnumerator() {
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return _table.GetEnumerator();
}
-
- public override IDictionaryEnumerator GetEnumerator() {
+
+ public override IDictionaryEnumerator GetEnumerator()
+ {
return _table.GetEnumerator();
}
-
- public override ICollection Keys {
- get {
- lock(_table.SyncRoot) {
+
+ public override ICollection Keys
+ {
+ get
+ {
+ lock (_table.SyncRoot)
+ {
return _table.Keys;
}
}
}
-
- public override ICollection Values {
- get {
- lock(_table.SyncRoot) {
+
+ public override ICollection Values
+ {
+ get
+ {
+ lock (_table.SyncRoot)
+ {
return _table.Values;
}
}
}
-
- public override void Remove(Object key) {
- lock(_table.SyncRoot) {
+
+ public override void Remove(Object key)
+ {
+ lock (_table.SyncRoot)
+ {
_table.Remove(key);
}
}
-
+
/*==============================OnDeserialization===============================
**Action: Does nothing. We have to implement this because our parent HT implements it,
** but it doesn't do anything meaningful. The real work will be done when we
@@ -1210,13 +1337,13 @@ namespace System.Collections {
**Arguments: None
**Exceptions: None
==============================================================================*/
- public override void OnDeserialization(Object sender) {
+ public override void OnDeserialization(Object sender)
+ {
return;
}
-
}
-
-
+
+
// Implements an enumerator for a hashtable. The enumerator uses the
// internal version number of the hashtabke to ensure that no modifications
// are made to the hashtable while an enumeration is in progress.
@@ -1230,12 +1357,13 @@ namespace System.Collections {
private int getObjectRetType; // What should GetObject return?
private Object currentKey;
private Object currentValue;
-
+
internal const int Keys = 1;
internal const int Values = 2;
internal const int DictEntry = 3;
-
- internal HashtableEnumerator(Hashtable hashtable, int getObjRetType) {
+
+ internal HashtableEnumerator(Hashtable hashtable, int getObjRetType)
+ {
this.hashtable = hashtable;
bucket = hashtable.buckets.Length;
version = hashtable.version;
@@ -1243,23 +1371,29 @@ namespace System.Collections {
getObjectRetType = getObjRetType;
}
- public Object Clone() {
+ public Object Clone()
+ {
return MemberwiseClone();
}
-
- public virtual Object Key {
- get {
- if (current == false) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
+
+ public virtual Object Key
+ {
+ get
+ {
+ if (current == false) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
return currentKey;
}
}
-
- public virtual bool MoveNext() {
- if (version != hashtable.version) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
- while (bucket > 0) {
+
+ public virtual bool MoveNext()
+ {
+ if (version != hashtable.version) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
+ while (bucket > 0)
+ {
bucket--;
Object keyv = hashtable.buckets[bucket].key;
- if ((keyv!= null) && (keyv != hashtable.buckets)) {
+ if ((keyv != null) && (keyv != hashtable.buckets))
+ {
currentKey = keyv;
currentValue = hashtable.buckets[bucket].val;
current = true;
@@ -1269,54 +1403,61 @@ namespace System.Collections {
current = false;
return false;
}
-
- public virtual DictionaryEntry Entry {
- get {
- if (current == false) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumOpCantHappen));
+
+ public virtual DictionaryEntry Entry
+ {
+ get
+ {
+ if (current == false) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumOpCantHappen));
return new DictionaryEntry(currentKey, currentValue);
}
}
-
-
- public virtual Object Current {
- get {
- if (current == false) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumOpCantHappen));
-
- if (getObjectRetType==Keys)
+
+
+ public virtual Object Current
+ {
+ get
+ {
+ if (current == false) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumOpCantHappen));
+
+ if (getObjectRetType == Keys)
return currentKey;
- else if (getObjectRetType==Values)
+ else if (getObjectRetType == Values)
return currentValue;
- else
+ else
return new DictionaryEntry(currentKey, currentValue);
}
}
-
- public virtual Object Value {
- get {
- if (current == false) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumOpCantHappen));
+
+ public virtual Object Value
+ {
+ get
+ {
+ if (current == false) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumOpCantHappen));
return currentValue;
}
}
-
- public virtual void Reset() {
- if (version != hashtable.version) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
+
+ public virtual void Reset()
+ {
+ if (version != hashtable.version) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
current = false;
bucket = hashtable.buckets.Length;
currentKey = null;
currentValue = null;
}
}
-
+
// internal debug view class for hashtable
- internal class HashtableDebugView {
- private Hashtable hashtable;
- }
+ internal class HashtableDebugView
+ {
+ private Hashtable hashtable;
+ }
}
[FriendAccessAllowed]
internal static class HashHelpers
{
-
#if FEATURE_RANDOMIZED_STRING_HASHING
public const int HashCollisionThreshold = 100;
public static bool s_UseRandomizedStringHashing = String.UseRandomizedHashing();
@@ -1344,11 +1485,11 @@ namespace System.Collections {
// object until OnDeserialization is called.
private static ConditionalWeakTable<object, SerializationInfo> s_SerializationInfoTable;
- internal static ConditionalWeakTable<object, SerializationInfo> SerializationInfoTable
- {
- get
- {
- if(s_SerializationInfoTable == null)
+ internal static ConditionalWeakTable<object, SerializationInfo> SerializationInfoTable
+ {
+ get
+ {
+ if (s_SerializationInfoTable == null)
{
ConditionalWeakTable<object, SerializationInfo> newTable = new ConditionalWeakTable<object, SerializationInfo>();
Interlocked.CompareExchange(ref s_SerializationInfoTable, newTable, null);
@@ -1356,15 +1497,14 @@ namespace System.Collections {
return s_SerializationInfoTable;
}
-
}
- public static bool IsPrime(int candidate)
+ public static bool IsPrime(int candidate)
{
- if ((candidate & 1) != 0)
+ if ((candidate & 1) != 0)
{
- int limit = (int)Math.Sqrt (candidate);
- for (int divisor = 3; divisor <= limit; divisor+=2)
+ int limit = (int)Math.Sqrt(candidate);
+ for (int divisor = 3; divisor <= limit; divisor += 2)
{
if ((candidate % divisor) == 0)
return false;
@@ -1374,13 +1514,13 @@ namespace System.Collections {
return (candidate == 2);
}
- public static int GetPrime(int min)
+ public static int GetPrime(int min)
{
if (min < 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_HTCapacityOverflow"));
+ throw new ArgumentException(SR.Arg_HTCapacityOverflow);
Contract.EndContractBlock();
- for (int i = 0; i < primes.Length; i++)
+ for (int i = 0; i < primes.Length; i++)
{
int prime = primes[i];
if (prime >= min) return prime;
@@ -1388,7 +1528,7 @@ namespace System.Collections {
//outside of our predefined table.
//compute the hard way.
- for (int i = (min | 1); i < Int32.MaxValue;i+=2)
+ for (int i = (min | 1); i < Int32.MaxValue; i += 2)
{
if (IsPrime(i) && ((i - 1) % Hashtable.HashPrime != 0))
return i;
@@ -1405,7 +1545,7 @@ namespace System.Collections {
// Note that this check works even when _items.Length overflowed thanks to the (uint) cast
if ((uint)newSize > MaxPrimeArrayLength && MaxPrimeArrayLength > oldSize)
{
- Debug.Assert( MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength");
+ Debug.Assert(MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength");
return MaxPrimeArrayLength;
}
@@ -1415,29 +1555,5 @@ namespace System.Collections {
// This is the maximum prime smaller than Array.MaxArrayLength
public const int MaxPrimeArrayLength = 0x7FEFFFFD;
-
-#if FEATURE_RANDOMIZED_STRING_HASHING
-
- public static object GetEqualityComparerForSerialization(object comparer)
- {
- if(comparer == null)
- {
- return null;
- }
-
- IWellKnownStringEqualityComparer cmp = comparer as IWellKnownStringEqualityComparer;
-
- if(cmp != null)
- {
- return cmp.GetEqualityComparerForSerialization();
- }
-
- return comparer;
- }
-
- private const int bufferSize = 1024;
- private static int currentIndex = bufferSize;
- private static readonly object lockObj = new Object();
-#endif // FEATURE_RANDOMIZED_STRING_HASHING
}
}
diff --git a/src/mscorlib/src/System/Collections/ICollection.cs b/src/mscorlib/src/System/Collections/ICollection.cs
deleted file mode 100644
index 088928a0ef..0000000000
--- a/src/mscorlib/src/System/Collections/ICollection.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: ICollection
-**
-**
-**
-**
-** Purpose: Base interface for all collections.
-**
-**
-===========================================================*/
-namespace System.Collections {
- using System;
- using System.Diagnostics.Contracts;
-
- // Base interface for all collections, defining enumerators, size, and
- // synchronization methods.
- public interface ICollection : IEnumerable
- {
- // Interfaces are not serialable
- // CopyTo copies a collection into an Array, starting at a particular
- // index into the array.
- //
- void CopyTo(Array array, int index);
-
- // Number of items in the collections.
- int Count
- { get; }
-
-
- // SyncRoot will return an Object to use for synchronization
- // (thread safety). You can use this object in your code to take a
- // lock on the collection, even if this collection is a wrapper around
- // another collection. The intent is to tunnel through to a real
- // implementation of a collection, and use one of the internal objects
- // found in that code.
- //
- // In the absense of a static Synchronized method on a collection,
- // the expected usage for SyncRoot would look like this:
- //
- // ICollection col = ...
- // lock (col.SyncRoot) {
- // // Some operation on the collection, which is now thread safe.
- // // This may include multiple operations.
- // }
- //
- //
- // The system-provided collections have a static method called
- // Synchronized which will create a thread-safe wrapper around the
- // collection. All access to the collection that you want to be
- // thread-safe should go through that wrapper collection. However, if
- // you need to do multiple calls on that collection (such as retrieving
- // two items, or checking the count then doing something), you should
- // NOT use our thread-safe wrapper since it only takes a lock for the
- // duration of a single method call. Instead, use Monitor.Enter/Exit
- // or your language's equivalent to the C# lock keyword as mentioned
- // above.
- //
- // For collections with no publically available underlying store, the
- // expected implementation is to simply return the this pointer. Note
- // that the this pointer may not be sufficient for collections that
- // wrap other collections; those should return the underlying
- // collection's SyncRoot property.
- Object SyncRoot
- { get; }
-
- // Is this collection synchronized (i.e., thread-safe)? If you want a
- // thread-safe collection, you can use SyncRoot as an object to
- // synchronize your collection with. If you're using one of the
- // collections in System.Collections, you could call the static
- // Synchronized method to get a thread-safe wrapper around the
- // underlying collection.
- bool IsSynchronized
- { get; }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IComparer.cs b/src/mscorlib/src/System/Collections/IComparer.cs
deleted file mode 100644
index 574af1a768..0000000000
--- a/src/mscorlib/src/System/Collections/IComparer.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IComparer
-**
-**
-**
-**
-** Purpose: Interface for comparing two Objects.
-**
-**
-===========================================================*/
-namespace System.Collections {
-
- using System;
- // The IComparer interface implements a method that compares two objects. It is
- // used in conjunction with the Sort and BinarySearch methods on
- // the Array and List classes.
- //
- // Interfaces are not serializable
- public interface IComparer {
- // Compares two objects. An implementation of this method must return a
- // value less than zero if x is less than y, zero if x is equal to y, or a
- // value greater than zero if x is greater than y.
- //
- int Compare(Object x, Object y);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IDictionary.cs b/src/mscorlib/src/System/Collections/IDictionary.cs
deleted file mode 100644
index 519d53ed55..0000000000
--- a/src/mscorlib/src/System/Collections/IDictionary.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IDictionary
-**
-**
-**
-**
-** Purpose: Base interface for all dictionaries.
-**
-**
-===========================================================*/
-namespace System.Collections {
- using System;
- using System.Diagnostics.Contracts;
-
- // An IDictionary is a possibly unordered set of key-value pairs.
- // Keys can be any non-null object. Values can be any object.
- // You can look up a value in an IDictionary via the default indexed
- // property, Items.
- public interface IDictionary : ICollection
- {
- // Interfaces are not serializable
- // The Item property provides methods to read and edit entries
- // in the Dictionary.
- Object this[Object key] {
- get;
- set;
- }
-
- // Returns a collections of the keys in this dictionary.
- ICollection Keys {
- get;
- }
-
- // Returns a collections of the values in this dictionary.
- ICollection Values {
- get;
- }
-
- // Returns whether this dictionary contains a particular key.
- //
- bool Contains(Object key);
-
- // Adds a key-value pair to the dictionary.
- //
- void Add(Object key, Object value);
-
- // Removes all pairs from the dictionary.
- void Clear();
-
- bool IsReadOnly
- { get; }
-
- bool IsFixedSize
- { get; }
-
- // Returns an IDictionaryEnumerator for this dictionary.
- new IDictionaryEnumerator GetEnumerator();
-
- // Removes a particular key from the dictionary.
- //
- void Remove(Object key);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IDictionaryEnumerator.cs b/src/mscorlib/src/System/Collections/IDictionaryEnumerator.cs
deleted file mode 100644
index 2f1add682c..0000000000
--- a/src/mscorlib/src/System/Collections/IDictionaryEnumerator.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IDictionaryEnumerator
-**
-**
-**
-**
-** Purpose: Base interface for dictionary enumerators.
-**
-**
-===========================================================*/
-namespace System.Collections {
- // Interfaces are not serializable
-
- using System;
- // This interface represents an enumerator that allows sequential access to the
- // elements of a dictionary. Upon creation, an enumerator is conceptually
- // positioned before the first element of the enumeration. The first call to the
- // MoveNext method brings the first element of the enumeration into view,
- // and each successive call to MoveNext brings the next element into
- // view until MoveNext returns false, indicating that there are no more
- // elements to enumerate. Following each call to MoveNext, the
- // Key and Value methods are used to obtain the key and
- // value of the element currently in view. The values returned by calls to
- // Key and Value are undefined before the first call to
- // MoveNext and following a call to MoveNext that returned false.
- // Enumerators are typically used in while loops of the form
- //
- // IDictionaryEnumerator e = ...;
- // while (e.MoveNext()) {
- // Object key = e.Key;
- // Object value = e.Value;
- // ...
- // }
- //
- // The IDictionaryEnumerator interface extends the IEnumerator
- // inerface and can thus be used as a regular enumerator. The Current
- // method of an IDictionaryEnumerator returns a DictionaryEntry containing
- // the current key and value pair. However, the GetEntry method will
- // return the same DictionaryEntry and avoids boxing the DictionaryEntry (boxing
- // is somewhat expensive).
- //
- public interface IDictionaryEnumerator : IEnumerator
- {
- // Returns the key of the current element of the enumeration. The returned
- // value is undefined before the first call to GetNext and following
- // a call to GetNext that returned false. Multiple calls to
- // GetKey with no intervening calls to GetNext will return
- // the same object.
- //
- Object Key {
- get;
- }
-
- // Returns the value of the current element of the enumeration. The
- // returned value is undefined before the first call to GetNext and
- // following a call to GetNext that returned false. Multiple calls
- // to GetValue with no intervening calls to GetNext will
- // return the same object.
- //
- Object Value {
- get;
- }
-
- // GetBlock will copy dictionary values into the given Array. It will either
- // fill up the array, or if there aren't enough elements, it will
- // copy as much as possible into the Array. The number of elements
- // copied is returned.
- //
- DictionaryEntry Entry {
- get;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IEnumerable.cs b/src/mscorlib/src/System/Collections/IEnumerable.cs
deleted file mode 100644
index 1d8e71cf07..0000000000
--- a/src/mscorlib/src/System/Collections/IEnumerable.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IEnumerable
-**
-**
-**
-**
-** Purpose: Interface for classes providing IEnumerators
-**
-**
-===========================================================*/
-namespace System.Collections {
- using System;
- using System.Diagnostics.Contracts;
- using System.Runtime.InteropServices;
-
- // Implement this interface if you need to support VB's foreach semantics.
- // Also, COM classes that support an enumerator will also implement this interface.
- [Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
- public interface IEnumerable
- {
- // Interfaces are not serializable
- // Returns an IEnumerator for this enumerable Object. The enumerator provides
- // a simple way to access all the contents of a collection.
- [Pure]
- [DispId(-4)]
- IEnumerator GetEnumerator();
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IEnumerator.cs b/src/mscorlib/src/System/Collections/IEnumerator.cs
deleted file mode 100644
index 4c4fc085e8..0000000000
--- a/src/mscorlib/src/System/Collections/IEnumerator.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IEnumerator
-**
-**
-**
-**
-** Purpose: Base interface for all enumerators.
-**
-**
-===========================================================*/
-namespace System.Collections {
- using System;
- using System.Runtime.InteropServices;
-
- // Base interface for all enumerators, providing a simple approach
- // to iterating over a collection.
- [Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
- public interface IEnumerator
- {
- // Interfaces are not serializable
- // Advances the enumerator to the next element of the enumeration and
- // returns a boolean indicating whether an element is available. Upon
- // creation, an enumerator is conceptually positioned before the first
- // element of the enumeration, and the first call to MoveNext
- // brings the first element of the enumeration into view.
- //
- bool MoveNext();
-
- // Returns the current element of the enumeration. The returned value is
- // undefined before the first call to MoveNext and following a
- // call to MoveNext that returned false. Multiple calls to
- // GetCurrent with no intervening calls to MoveNext
- // will return the same object.
- //
- Object Current {
- get;
- }
-
- // Resets the enumerator to the beginning of the enumeration, starting over.
- // The preferred behavior for Reset is to return the exact same enumeration.
- // This means if you modify the underlying collection then call Reset, your
- // IEnumerator will be invalid, just as it would have been if you had called
- // MoveNext or Current.
- //
- void Reset();
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IEqualityComparer.cs b/src/mscorlib/src/System/Collections/IEqualityComparer.cs
deleted file mode 100644
index f591b11152..0000000000
--- a/src/mscorlib/src/System/Collections/IEqualityComparer.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IEqualityComparer
-**
-**
-**
-**
-** Purpose: A mechanism to expose a simplified infrastructure for
-** Comparing objects in collections.
-**
-**
-===========================================================*/
-namespace System.Collections {
-
- using System;
- // An IEqualityComparer is a mechanism to consume custom performant comparison infrastructure
- // that can be consumed by some of the common collections.
- public interface IEqualityComparer {
- bool Equals(Object x, Object y);
- int GetHashCode(Object obj);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IHashCodeProvider.cs b/src/mscorlib/src/System/Collections/IHashCodeProvider.cs
index 0ae1e3295b..fa4738ab64 100644
--- a/src/mscorlib/src/System/Collections/IHashCodeProvider.cs
+++ b/src/mscorlib/src/System/Collections/IHashCodeProvider.cs
@@ -13,17 +13,19 @@
**
**
===========================================================*/
-namespace System.Collections {
-
- using System;
+
+using System;
+
+namespace System.Collections
+{
// Provides a mechanism for a hash table user to override the default
// GetHashCode() function on Objects, providing their own hash function.
[Obsolete("Please use IEqualityComparer instead.")]
- internal interface IHashCodeProvider
+ internal interface IHashCodeProvider
{
// Interfaces are not serializable
// Returns a hash code for the given object.
//
- int GetHashCode (Object obj);
+ int GetHashCode(Object obj);
}
}
diff --git a/src/mscorlib/src/System/Collections/IList.cs b/src/mscorlib/src/System/Collections/IList.cs
deleted file mode 100644
index 8b63400852..0000000000
--- a/src/mscorlib/src/System/Collections/IList.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-** Interface: IList
-**
-**
-**
-**
-** Purpose: Base interface for all Lists.
-**
-**
-===========================================================*/
-namespace System.Collections {
-
- using System;
- using System.Diagnostics.Contracts;
-
- // An IList is an ordered collection of objects. The exact ordering
- // is up to the implementation of the list, ranging from a sorted
- // order to insertion order.
- public interface IList : ICollection
- {
- // The Item property provides methods to read and edit entries in the List.
- Object this[int index] {
- get;
- set;
- }
-
- // Adds an item to the list. The exact position in the list is
- // implementation-dependent, so while ArrayList may always insert
- // in the last available location, a SortedList most likely would not.
- // The return value is the position the new element was inserted in.
- int Add(Object value);
-
- // Returns whether the list contains a particular item.
- bool Contains(Object value);
-
- // Removes all items from the list.
- void Clear();
-
- bool IsReadOnly
- { get; }
-
-
- bool IsFixedSize
- {
- get;
- }
-
-
- // Returns the index of a particular item, if it is in the list.
- // Returns -1 if the item isn't in the list.
- int IndexOf(Object value);
-
- // Inserts value into the list at position index.
- // index must be non-negative and less than or equal to the
- // number of elements in the list. If index equals the number
- // of items in the list, then value is appended to the end.
- void Insert(int index, Object value);
-
- // Removes an item from the list.
- void Remove(Object value);
-
- // Removes the item at position index.
- void RemoveAt(int index);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IStructuralComparable.cs b/src/mscorlib/src/System/Collections/IStructuralComparable.cs
deleted file mode 100644
index 1b6f3aff7a..0000000000
--- a/src/mscorlib/src/System/Collections/IStructuralComparable.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// 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;
-
-namespace System.Collections {
-
- public interface IStructuralComparable {
- Int32 CompareTo(Object other, IComparer comparer);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IStructuralEquatable.cs b/src/mscorlib/src/System/Collections/IStructuralEquatable.cs
deleted file mode 100644
index 5a5295fc38..0000000000
--- a/src/mscorlib/src/System/Collections/IStructuralEquatable.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-namespace System.Collections {
-
- public interface IStructuralEquatable {
- Boolean Equals(Object other, IEqualityComparer comparer);
- int GetHashCode(IEqualityComparer comparer);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs b/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs
index 617c33707a..3f92038d4f 100644
--- a/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs
+++ b/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs
@@ -11,55 +11,70 @@
**
**
===========================================================*/
+
using System.Diagnostics.Contracts;
-namespace System.Collections {
+
+namespace System.Collections
+{
/// This is a simple implementation of IDictionary using a singly linked list. This
/// will be smaller and faster than a Hashtable if the number of elements is 10 or less.
/// This should not be used if performance is important for large numbers of elements.
[Serializable]
- internal class ListDictionaryInternal: IDictionary {
- DictionaryNode head;
- int version;
- int count;
+ internal class ListDictionaryInternal : IDictionary
+ {
+ private DictionaryNode head;
+ private int version;
+ private int count;
[NonSerialized]
private Object _syncRoot;
- public ListDictionaryInternal() {
+ public ListDictionaryInternal()
+ {
}
- public Object this[Object key] {
- get {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public Object this[Object key]
+ {
+ get
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
DictionaryNode node = head;
- while (node != null) {
- if ( node.key.Equals(key) ) {
+ while (node != null)
+ {
+ if (node.key.Equals(key))
+ {
return node.value;
}
node = node.next;
}
return null;
}
- set {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ set
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
-
+
version++;
DictionaryNode last = null;
DictionaryNode node;
- for (node = head; node != null; node = node.next) {
- if( node.key.Equals(key) ) {
+ for (node = head; node != null; node = node.next)
+ {
+ if (node.key.Equals(key))
+ {
break;
- }
+ }
last = node;
}
- if (node != null) {
+ if (node != null)
+ {
// Found it
node.value = value;
return;
@@ -68,78 +83,100 @@ namespace System.Collections {
DictionaryNode newNode = new DictionaryNode();
newNode.key = key;
newNode.value = value;
- if (last != null) {
+ if (last != null)
+ {
last.next = newNode;
}
- else {
+ else
+ {
head = newNode;
}
count++;
}
}
- public int Count {
- get {
+ public int Count
+ {
+ get
+ {
return count;
}
- }
+ }
- public ICollection Keys {
- get {
+ public ICollection Keys
+ {
+ get
+ {
return new NodeKeyValueCollection(this, true);
}
}
- public bool IsReadOnly {
- get {
+ public bool IsReadOnly
+ {
+ get
+ {
return false;
}
}
- public bool IsFixedSize {
- get {
+ public bool IsFixedSize
+ {
+ get
+ {
return false;
}
}
- public bool IsSynchronized {
- get {
+ public bool IsSynchronized
+ {
+ get
+ {
return false;
}
}
- public Object SyncRoot {
- get {
- if( _syncRoot == null) {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ public Object SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
- return _syncRoot;
+ return _syncRoot;
}
}
- public ICollection Values {
- get {
+ public ICollection Values
+ {
+ get
+ {
return new NodeKeyValueCollection(this, false);
}
}
- public void Add(Object key, Object value) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public void Add(Object key, Object value)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
-
+
version++;
DictionaryNode last = null;
DictionaryNode node;
- for (node = head; node != null; node = node.next) {
- if (node.key.Equals(key)) {
- throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate__", node.key, key));
- }
+ for (node = head; node != null; node = node.next)
+ {
+ if (node.key.Equals(key))
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_AddingDuplicate__, node.key, key));
+ }
last = node;
}
- if (node != null) {
+ if (node != null)
+ {
// Found it
node.value = value;
return;
@@ -148,265 +185,328 @@ namespace System.Collections {
DictionaryNode newNode = new DictionaryNode();
newNode.key = key;
newNode.value = value;
- if (last != null) {
+ if (last != null)
+ {
last.next = newNode;
}
- else {
+ else
+ {
head = newNode;
}
count++;
}
- public void Clear() {
+ public void Clear()
+ {
count = 0;
head = null;
version++;
}
- public bool Contains(Object key) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public bool Contains(Object key)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
- for (DictionaryNode node = head; node != null; node = node.next) {
- if (node.key.Equals(key)) {
+ for (DictionaryNode node = head; node != null; node = node.next)
+ {
+ if (node.key.Equals(key))
+ {
return true;
}
}
return false;
}
- public void CopyTo(Array array, int index) {
- if (array==null)
+ public void CopyTo(Array array, int index)
+ {
+ if (array == null)
throw new ArgumentNullException(nameof(array));
-
+
if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
- if ( array.Length - index < this.Count )
- throw new ArgumentException( Environment.GetResourceString("ArgumentOutOfRange_Index"), nameof(index));
+ if (array.Length - index < this.Count)
+ throw new ArgumentException(SR.ArgumentOutOfRange_Index, nameof(index));
Contract.EndContractBlock();
- for (DictionaryNode node = head; node != null; node = node.next) {
+ for (DictionaryNode node = head; node != null; node = node.next)
+ {
array.SetValue(new DictionaryEntry(node.key, node.value), index);
index++;
}
}
- public IDictionaryEnumerator GetEnumerator() {
+ public IDictionaryEnumerator GetEnumerator()
+ {
return new NodeEnumerator(this);
}
- IEnumerator IEnumerable.GetEnumerator() {
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return new NodeEnumerator(this);
}
- public void Remove(Object key) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public void Remove(Object key)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
version++;
DictionaryNode last = null;
DictionaryNode node;
- for (node = head; node != null; node = node.next) {
- if (node.key.Equals(key)) {
+ for (node = head; node != null; node = node.next)
+ {
+ if (node.key.Equals(key))
+ {
break;
- }
+ }
last = node;
}
- if (node == null) {
+ if (node == null)
+ {
return;
- }
- if (node == head) {
+ }
+ if (node == head)
+ {
head = node.next;
- } else {
+ }
+ else
+ {
last.next = node.next;
}
count--;
}
- private class NodeEnumerator : IDictionaryEnumerator {
- ListDictionaryInternal list;
- DictionaryNode current;
- int version;
- bool start;
+ private class NodeEnumerator : IDictionaryEnumerator
+ {
+ private ListDictionaryInternal list;
+ private DictionaryNode current;
+ private int version;
+ private bool start;
- public NodeEnumerator(ListDictionaryInternal list) {
+ public NodeEnumerator(ListDictionaryInternal list)
+ {
this.list = list;
version = list.version;
start = true;
current = null;
}
- public Object Current {
- get {
+ public Object Current
+ {
+ get
+ {
return Entry;
}
}
- public DictionaryEntry Entry {
- get {
- if (current == null) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public DictionaryEntry Entry
+ {
+ get
+ {
+ if (current == null)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
return new DictionaryEntry(current.key, current.value);
}
}
- public Object Key {
- get {
- if (current == null) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public Object Key
+ {
+ get
+ {
+ if (current == null)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
return current.key;
}
}
- public Object Value {
- get {
- if (current == null) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public Object Value
+ {
+ get
+ {
+ if (current == null)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
return current.value;
}
}
- public bool MoveNext() {
- if (version != list.version) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
+ public bool MoveNext()
+ {
+ if (version != list.version)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
}
- if (start) {
+ if (start)
+ {
current = list.head;
start = false;
}
- else {
- if( current != null ) {
+ else
+ {
+ if (current != null)
+ {
current = current.next;
}
}
return (current != null);
}
- public void Reset() {
- if (version != list.version) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
+ public void Reset()
+ {
+ if (version != list.version)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
}
start = true;
current = null;
}
-
}
- private class NodeKeyValueCollection : ICollection {
- ListDictionaryInternal list;
- bool isKeys;
+ private class NodeKeyValueCollection : ICollection
+ {
+ private ListDictionaryInternal list;
+ private bool isKeys;
- public NodeKeyValueCollection(ListDictionaryInternal list, bool isKeys) {
+ public NodeKeyValueCollection(ListDictionaryInternal list, bool isKeys)
+ {
this.list = list;
this.isKeys = isKeys;
}
- void ICollection.CopyTo(Array array, int index) {
- if (array==null)
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
- if (array.Length - index < list.Count)
- throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Index"), nameof(index));
- for (DictionaryNode node = list.head; node != null; node = node.next) {
+ if (array.Length - index < list.Count)
+ throw new ArgumentException(SR.ArgumentOutOfRange_Index, nameof(index));
+ for (DictionaryNode node = list.head; node != null; node = node.next)
+ {
array.SetValue(isKeys ? node.key : node.value, index);
index++;
}
}
- int ICollection.Count {
- get {
+ int ICollection.Count
+ {
+ get
+ {
int count = 0;
- for (DictionaryNode node = list.head; node != null; node = node.next) {
+ for (DictionaryNode node = list.head; node != null; node = node.next)
+ {
count++;
}
return count;
}
- }
+ }
- bool ICollection.IsSynchronized {
- get {
+ bool ICollection.IsSynchronized
+ {
+ get
+ {
return false;
}
}
- Object ICollection.SyncRoot {
- get {
+ Object ICollection.SyncRoot
+ {
+ get
+ {
return list.SyncRoot;
}
}
- IEnumerator IEnumerable.GetEnumerator() {
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return new NodeKeyValueEnumerator(list, isKeys);
}
- private class NodeKeyValueEnumerator: IEnumerator {
- ListDictionaryInternal list;
- DictionaryNode current;
- int version;
- bool isKeys;
- bool start;
+ private class NodeKeyValueEnumerator : IEnumerator
+ {
+ private ListDictionaryInternal list;
+ private DictionaryNode current;
+ private int version;
+ private bool isKeys;
+ private bool start;
- public NodeKeyValueEnumerator(ListDictionaryInternal list, bool isKeys) {
+ public NodeKeyValueEnumerator(ListDictionaryInternal list, bool isKeys)
+ {
this.list = list;
this.isKeys = isKeys;
- this.version = list.version;
- this.start = true;
- this.current = null;
+ version = list.version;
+ start = true;
+ current = null;
}
- public Object Current {
- get {
- if (current == null) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public Object Current
+ {
+ get
+ {
+ if (current == null)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
return isKeys ? current.key : current.value;
}
}
- public bool MoveNext() {
- if (version != list.version) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
+ public bool MoveNext()
+ {
+ if (version != list.version)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
}
- if (start) {
+ if (start)
+ {
current = list.head;
start = false;
}
- else {
- if( current != null) {
+ else
+ {
+ if (current != null)
+ {
current = current.next;
}
}
return (current != null);
}
- public void Reset() {
- if (version != list.version) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
+ public void Reset()
+ {
+ if (version != list.version)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
}
start = true;
current = null;
}
- }
+ }
}
[Serializable]
- private class DictionaryNode {
+ private class DictionaryNode
+ {
public Object key;
public Object value;
public DictionaryNode next;
diff --git a/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs b/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs
index b3b19fb616..d9801dfaaf 100644
--- a/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs
+++ b/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs
@@ -4,50 +4,59 @@
//
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime;
+
namespace System.Collections.ObjectModel
{
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Runtime;
-
[Serializable]
[DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
- [DebuggerDisplay("Count = {Count}")]
- public class Collection<T>: IList<T>, IList, IReadOnlyList<T>
+ [DebuggerDisplay("Count = {Count}")]
+ public class Collection<T> : IList<T>, IList, IReadOnlyList<T>
{
- IList<T> items;
+ private IList<T> items;
[NonSerialized]
private Object _syncRoot;
- public Collection() {
+ public Collection()
+ {
items = new List<T>();
}
- public Collection(IList<T> list) {
- if (list == null) {
+ public Collection(IList<T> list)
+ {
+ if (list == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.list);
}
items = list;
}
- public int Count {
+ public int Count
+ {
get { return items.Count; }
}
- protected IList<T> Items {
+ protected IList<T> Items
+ {
get { return items; }
}
- public T this[int index] {
+ public T this[int index]
+ {
get { return items[index]; }
- set {
- if( items.IsReadOnly) {
+ set
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
-
- if (index < 0 || index >= items.Count) {
+
+ if (index < 0 || index >= items.Count)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
@@ -55,154 +64,192 @@ namespace System.Collections.ObjectModel
}
}
- public void Add(T item) {
- if( items.IsReadOnly) {
+ public void Add(T item)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
-
+
int index = items.Count;
InsertItem(index, item);
}
- public void Clear() {
- if( items.IsReadOnly) {
+ public void Clear()
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
-
+
ClearItems();
}
- public void CopyTo(T[] array, int index) {
+ public void CopyTo(T[] array, int index)
+ {
items.CopyTo(array, index);
}
- public bool Contains(T item) {
+ public bool Contains(T item)
+ {
return items.Contains(item);
}
- public IEnumerator<T> GetEnumerator() {
+ public IEnumerator<T> GetEnumerator()
+ {
return items.GetEnumerator();
}
- public int IndexOf(T item) {
+ public int IndexOf(T item)
+ {
return items.IndexOf(item);
}
- public void Insert(int index, T item) {
- if (items.IsReadOnly) {
+ public void Insert(int index, T item)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- if (index < 0 || index > items.Count) {
+ if (index < 0 || index > items.Count)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_ListInsert);
}
InsertItem(index, item);
}
- public bool Remove(T item) {
- if( items.IsReadOnly) {
+ public bool Remove(T item)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
-
+
int index = items.IndexOf(item);
if (index < 0) return false;
RemoveItem(index);
return true;
}
- public void RemoveAt(int index) {
- if( items.IsReadOnly) {
+ public void RemoveAt(int index)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- if (index < 0 || index >= items.Count) {
+ if (index < 0 || index >= items.Count)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
RemoveItem(index);
}
- protected virtual void ClearItems() {
+ protected virtual void ClearItems()
+ {
items.Clear();
}
- protected virtual void InsertItem(int index, T item) {
+ protected virtual void InsertItem(int index, T item)
+ {
items.Insert(index, item);
}
-
- protected virtual void RemoveItem(int index) {
+
+ protected virtual void RemoveItem(int index)
+ {
items.RemoveAt(index);
}
- protected virtual void SetItem(int index, T item) {
+ protected virtual void SetItem(int index, T item)
+ {
items[index] = item;
}
-
- bool ICollection<T>.IsReadOnly {
- get {
- return items.IsReadOnly;
+
+ bool ICollection<T>.IsReadOnly
+ {
+ get
+ {
+ return items.IsReadOnly;
}
}
-
- IEnumerator IEnumerable.GetEnumerator() {
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return ((IEnumerable)items).GetEnumerator();
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- object ICollection.SyncRoot {
- get {
- if( _syncRoot == null) {
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
ICollection c = items as ICollection;
- if( c != null) {
+ if (c != null)
+ {
_syncRoot = c.SyncRoot;
}
- else {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ else
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
}
- return _syncRoot;
+ return _syncRoot;
}
}
- void ICollection.CopyTo(Array array, int index) {
- if (array == null) {
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
-
- if (array.Rank != 1) {
+
+ if (array.Rank != 1)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if( array.GetLowerBound(0) != 0 ) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
-
- if (index < 0 ) {
+
+ if (index < 0)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < Count) {
+ if (array.Length - index < Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
T[] tArray = array as T[];
- if (tArray != null) {
- items.CopyTo(tArray , index);
+ if (tArray != null)
+ {
+ items.CopyTo(tArray, index);
}
- else {
+ else
+ {
//
// Catch the obvious case assignment will fail.
// We can found all possible problems by doing the check though.
// For example, if the element type of the Array is derived from T,
// we can't figure out if we can successfully copy the element beforehand.
//
- Type targetType = array.GetType().GetElementType();
+ Type targetType = array.GetType().GetElementType();
Type sourceType = typeof(T);
- if(!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) {
+ if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType)))
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
@@ -211,51 +258,62 @@ namespace System.Collections.ObjectModel
// widening of primitive types here.
//
object[] objects = array as object[];
- if( objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
int count = items.Count;
- try {
- for (int i = 0; i < count; i++) {
+ try
+ {
+ for (int i = 0; i < count; i++)
+ {
objects[index++] = items[i];
}
}
- catch(ArrayTypeMismatchException) {
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
- }
+ }
}
- object IList.this[int index] {
+ object IList.this[int index]
+ {
get { return items[index]; }
- set {
+ set
+ {
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(value, ExceptionArgument.value);
- try {
- this[index] = (T)value;
+ try
+ {
+ this[index] = (T)value;
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
}
-
}
}
- bool IList.IsReadOnly {
- get {
+ bool IList.IsReadOnly
+ {
+ get
+ {
return items.IsReadOnly;
}
}
- bool IList.IsFixedSize {
- get {
+ bool IList.IsFixedSize
+ {
+ get
+ {
// There is no IList<T>.IsFixedSize, so we must assume that only
// readonly collections are fixed size, if our internal item
// collection does not implement IList. Note that Array implements
// IList, and therefore T[] and U[] will be fixed-size.
IList list = items as IList;
- if(list != null)
+ if (list != null)
{
return list.IsFixedSize;
}
@@ -263,62 +321,77 @@ namespace System.Collections.ObjectModel
}
}
- int IList.Add(object value) {
- if( items.IsReadOnly) {
+ int IList.Add(object value)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(value, ExceptionArgument.value);
-
- try {
+
+ try
+ {
Add((T)value);
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
- }
-
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
+ }
+
return this.Count - 1;
}
- bool IList.Contains(object value) {
- if(IsCompatibleObject(value)) {
- return Contains((T) value);
+ bool IList.Contains(object value)
+ {
+ if (IsCompatibleObject(value))
+ {
+ return Contains((T)value);
}
return false;
}
- int IList.IndexOf(object value) {
- if(IsCompatibleObject(value)) {
+ int IList.IndexOf(object value)
+ {
+ if (IsCompatibleObject(value))
+ {
return IndexOf((T)value);
- }
+ }
return -1;
}
- void IList.Insert(int index, object value) {
- if( items.IsReadOnly) {
+ void IList.Insert(int index, object value)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(value, ExceptionArgument.value);
-
- try {
+
+ try
+ {
Insert(index, (T)value);
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
- }
-
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
+ }
}
- void IList.Remove(object value) {
- if( items.IsReadOnly) {
+ void IList.Remove(object value)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- if(IsCompatibleObject(value)) {
- Remove((T) value);
- }
+ if (IsCompatibleObject(value))
+ {
+ Remove((T)value);
+ }
}
- private static bool IsCompatibleObject(object value) {
+ private static bool IsCompatibleObject(object value)
+ {
// Non-null values are fine. Only accept nulls if T is a class or Nullable<U>.
// Note that default(T) is not equal to null for value types except when T is Nullable<U>.
return ((value is T) || (value == null && default(T) == null));
diff --git a/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs b/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs
deleted file mode 100644
index 3fe7716203..0000000000
--- a/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs
+++ /dev/null
@@ -1,244 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-//
-
-namespace System.Collections.ObjectModel
-{
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- [Serializable]
- [DebuggerTypeProxy(typeof(Mscorlib_KeyedCollectionDebugView<,>))]
- [DebuggerDisplay("Count = {Count}")]
- public abstract class KeyedCollection<TKey,TItem>: Collection<TItem>
- {
- const int defaultThreshold = 0;
-
- IEqualityComparer<TKey> comparer;
- Dictionary<TKey,TItem> dict;
- int keyCount;
- int threshold;
-
- protected KeyedCollection(): this(null, defaultThreshold) {}
-
- protected KeyedCollection(IEqualityComparer<TKey> comparer): this(comparer, defaultThreshold) {}
-
-
- protected KeyedCollection(IEqualityComparer<TKey> comparer, int dictionaryCreationThreshold)
- : base(new List<TItem>()) { // Be explicit about the use of List<T> so we can foreach over
- // Items internally without enumerator allocations.
- if (comparer == null) {
- comparer = EqualityComparer<TKey>.Default;
- }
-
- if (dictionaryCreationThreshold == -1) {
- dictionaryCreationThreshold = int.MaxValue;
- }
-
- if( dictionaryCreationThreshold < -1) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.dictionaryCreationThreshold, ExceptionResource.ArgumentOutOfRange_InvalidThreshold);
- }
-
- this.comparer = comparer;
- this.threshold = dictionaryCreationThreshold;
- }
-
- /// <summary>
- /// Enables the use of foreach internally without allocations using <see cref="List{T}"/>'s struct enumerator.
- /// </summary>
- new private List<TItem> Items {
- get {
- Debug.Assert(base.Items is List<TItem>);
-
- return (List<TItem>)base.Items;
- }
- }
-
- public IEqualityComparer<TKey> Comparer {
- get {
- return comparer;
- }
- }
-
- public TItem this[TKey key] {
- get {
- if( key == null) {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- }
-
- if (dict != null) {
- return dict[key];
- }
-
- foreach (TItem item in Items) {
- if (comparer.Equals(GetKeyForItem(item), key)) return item;
- }
-
- ThrowHelper.ThrowKeyNotFoundException();
- return default(TItem);
- }
- }
-
- public bool Contains(TKey key) {
- if( key == null) {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- }
-
- if (dict != null) {
- return dict.ContainsKey(key);
- }
-
- foreach (TItem item in Items) {
- if (comparer.Equals(GetKeyForItem(item), key)) return true;
- }
- return false;
- }
-
- private bool ContainsItem(TItem item) {
- TKey key;
- if( (dict == null) || ((key = GetKeyForItem(item)) == null)) {
- return Items.Contains(item);
- }
-
- TItem itemInDict;
- bool exist = dict.TryGetValue(key, out itemInDict);
- if( exist) {
- return EqualityComparer<TItem>.Default.Equals(itemInDict, item);
- }
- return false;
- }
-
- public bool Remove(TKey key) {
- if( key == null) {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- }
-
- if (dict != null) {
- if (dict.ContainsKey(key)) {
- return Remove(dict[key]);
- }
-
- return false;
- }
-
- for (int i = 0; i < Items.Count; i++) {
- if (comparer.Equals(GetKeyForItem(Items[i]), key)) {
- RemoveItem(i);
- return true;
- }
- }
- return false;
- }
-
- protected IDictionary<TKey,TItem> Dictionary {
- get { return dict; }
- }
-
- protected void ChangeItemKey(TItem item, TKey newKey) {
- // check if the item exists in the collection
- if( !ContainsItem(item)) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_ItemNotExist);
- }
-
- TKey oldKey = GetKeyForItem(item);
- if (!comparer.Equals(oldKey, newKey)) {
- if (newKey != null) {
- AddKey(newKey, item);
- }
-
- if (oldKey != null) {
- RemoveKey(oldKey);
- }
- }
- }
-
- protected override void ClearItems() {
- base.ClearItems();
- if (dict != null) {
- dict.Clear();
- }
-
- keyCount = 0;
- }
-
- protected abstract TKey GetKeyForItem(TItem item);
-
- protected override void InsertItem(int index, TItem item) {
- TKey key = GetKeyForItem(item);
- if (key != null) {
- AddKey(key, item);
- }
- base.InsertItem(index, item);
- }
-
- protected override void RemoveItem(int index) {
- TKey key = GetKeyForItem(Items[index]);
- if (key != null) {
- RemoveKey(key);
- }
- base.RemoveItem(index);
- }
-
- protected override void SetItem(int index, TItem item) {
- TKey newKey = GetKeyForItem(item);
- TKey oldKey = GetKeyForItem(Items[index]);
-
- if (comparer.Equals(oldKey, newKey)) {
- if (newKey != null && dict != null) {
- dict[newKey] = item;
- }
- }
- else {
- if (newKey != null) {
- AddKey(newKey, item);
- }
-
- if (oldKey != null) {
- RemoveKey(oldKey);
- }
- }
- base.SetItem(index, item);
- }
-
- private void AddKey(TKey key, TItem item) {
- if (dict != null) {
- dict.Add(key, item);
- }
- else if (keyCount == threshold) {
- CreateDictionary();
- dict.Add(key, item);
- }
- else {
- if (Contains(key)) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
- }
-
- keyCount++;
- }
- }
-
- private void CreateDictionary() {
- dict = new Dictionary<TKey,TItem>(comparer);
- foreach (TItem item in Items) {
- TKey key = GetKeyForItem(item);
- if (key != null) {
- dict.Add(key, item);
- }
- }
- }
-
- private void RemoveKey(TKey key) {
- Debug.Assert(key != null, "key shouldn't be null!");
- if (dict != null) {
- dict.Remove(key);
- }
- else {
- keyCount--;
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs
index 10c48cf76d..b484879c27 100644
--- a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs
+++ b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs
@@ -4,150 +4,184 @@
//
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime;
+
namespace System.Collections.ObjectModel
{
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Runtime;
-
[Serializable]
[DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
- [DebuggerDisplay("Count = {Count}")]
- public class ReadOnlyCollection<T>: IList<T>, IList, IReadOnlyList<T>
+ [DebuggerDisplay("Count = {Count}")]
+ public class ReadOnlyCollection<T> : IList<T>, IList, IReadOnlyList<T>
{
- IList<T> list;
+ private IList<T> list;
[NonSerialized]
private Object _syncRoot;
- public ReadOnlyCollection(IList<T> list) {
- if (list == null) {
+ public ReadOnlyCollection(IList<T> list)
+ {
+ if (list == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.list);
}
this.list = list;
}
- public int Count {
+ public int Count
+ {
get { return list.Count; }
}
- public T this[int index] {
+ public T this[int index]
+ {
get { return list[index]; }
}
- public bool Contains(T value) {
+ public bool Contains(T value)
+ {
return list.Contains(value);
}
- public void CopyTo(T[] array, int index) {
+ public void CopyTo(T[] array, int index)
+ {
list.CopyTo(array, index);
}
- public IEnumerator<T> GetEnumerator() {
+ public IEnumerator<T> GetEnumerator()
+ {
return list.GetEnumerator();
}
- public int IndexOf(T value) {
+ public int IndexOf(T value)
+ {
return list.IndexOf(value);
}
- protected IList<T> Items {
- get {
+ protected IList<T> Items
+ {
+ get
+ {
return list;
}
}
- bool ICollection<T>.IsReadOnly {
+ bool ICollection<T>.IsReadOnly
+ {
get { return true; }
}
-
- T IList<T>.this[int index] {
+
+ T IList<T>.this[int index]
+ {
get { return list[index]; }
- set {
+ set
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
}
- void ICollection<T>.Add(T value) {
+ void ICollection<T>.Add(T value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
-
- void ICollection<T>.Clear() {
+
+ void ICollection<T>.Clear()
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- void IList<T>.Insert(int index, T value) {
+ void IList<T>.Insert(int index, T value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- bool ICollection<T>.Remove(T value) {
+ bool ICollection<T>.Remove(T value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
return false;
}
- void IList<T>.RemoveAt(int index) {
+ void IList<T>.RemoveAt(int index)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- IEnumerator IEnumerable.GetEnumerator() {
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return ((IEnumerable)list).GetEnumerator();
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- object ICollection.SyncRoot {
- get {
- if( _syncRoot == null) {
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
ICollection c = list as ICollection;
- if( c != null) {
+ if (c != null)
+ {
_syncRoot = c.SyncRoot;
}
- else {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ else
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
}
- return _syncRoot;
+ return _syncRoot;
}
}
- void ICollection.CopyTo(Array array, int index) {
- if (array==null) {
+ 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.Rank != 1)
+ {
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if( array.GetLowerBound(0) != 0 ) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
-
- if (index < 0) {
+
+ if (index < 0)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < Count) {
+ if (array.Length - index < Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
T[] items = array as T[];
- if (items != null) {
+ if (items != null)
+ {
list.CopyTo(items, index);
}
- else {
+ else
+ {
//
// Catch the obvious case assignment will fail.
// We can found all possible problems by doing the check though.
// For example, if the element type of the Array is derived from T,
// we can't figure out if we can successfully copy the element beforehand.
//
- Type targetType = array.GetType().GetElementType();
+ Type targetType = array.GetType().GetElementType();
Type sourceType = typeof(T);
- if(!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) {
+ if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType)))
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
@@ -156,76 +190,94 @@ namespace System.Collections.ObjectModel
// widening of primitive types here.
//
object[] objects = array as object[];
- if( objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
int count = list.Count;
- try {
- for (int i = 0; i < count; i++) {
+ try
+ {
+ for (int i = 0; i < count; i++)
+ {
objects[index++] = list[i];
}
}
- catch(ArrayTypeMismatchException) {
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
- bool IList.IsFixedSize {
+ bool IList.IsFixedSize
+ {
get { return true; }
}
- bool IList.IsReadOnly {
+ bool IList.IsReadOnly
+ {
get { return true; }
}
- object IList.this[int index] {
+ object IList.this[int index]
+ {
get { return list[index]; }
- set {
+ set
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
}
- int IList.Add(object value) {
+ int IList.Add(object value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
return -1;
}
- void IList.Clear() {
- ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ void IList.Clear()
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- private static bool IsCompatibleObject(object value) {
+ private static bool IsCompatibleObject(object value)
+ {
// Non-null values are fine. Only accept nulls if T is a class or Nullable<U>.
// Note that default(T) is not equal to null for value types except when T is Nullable<U>.
return ((value is T) || (value == null && default(T) == null));
}
- bool IList.Contains(object value) {
- if(IsCompatibleObject(value)) {
- return Contains((T) value);
+ bool IList.Contains(object value)
+ {
+ if (IsCompatibleObject(value))
+ {
+ return Contains((T)value);
}
return false;
}
- int IList.IndexOf(object value) {
- if(IsCompatibleObject(value)) {
+ int IList.IndexOf(object value)
+ {
+ if (IsCompatibleObject(value))
+ {
return IndexOf((T)value);
}
return -1;
}
- void IList.Insert(int index, object value) {
+ void IList.Insert(int index, object value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- void IList.Remove(object value) {
- ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ void IList.Remove(object value)
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- void IList.RemoveAt(int index) {
+ void IList.RemoveAt(int index)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
- }
+ }
}
}
diff --git a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs
index 5c9e8c44c6..ebf86cdc58 100644
--- a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs
+++ b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs
@@ -11,18 +11,18 @@
**
===========================================================*/
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
namespace System.Collections.ObjectModel
{
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
[Serializable]
[DebuggerTypeProxy(typeof(Mscorlib_DictionaryDebugView<,>))]
[DebuggerDisplay("Count = {Count}")]
- public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue>
+ internal class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue>
{
private readonly IDictionary<TKey, TValue> m_dictionary;
[NonSerialized]
@@ -32,32 +32,41 @@ namespace System.Collections.ObjectModel
[NonSerialized]
private ValueCollection m_values;
- public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary) {
- if (dictionary == null) {
+ public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
+ {
+ if (dictionary == null)
+ {
throw new ArgumentNullException(nameof(dictionary));
}
Contract.EndContractBlock();
m_dictionary = dictionary;
}
- protected IDictionary<TKey, TValue> Dictionary {
+ protected IDictionary<TKey, TValue> Dictionary
+ {
get { return m_dictionary; }
}
- public KeyCollection Keys {
- get {
+ public KeyCollection Keys
+ {
+ get
+ {
Contract.Ensures(Contract.Result<KeyCollection>() != null);
- if (m_keys == null) {
+ if (m_keys == null)
+ {
m_keys = new KeyCollection(m_dictionary.Keys);
}
return m_keys;
}
}
- public ValueCollection Values {
- get {
+ public ValueCollection Values
+ {
+ get
+ {
Contract.Ensures(Contract.Result<ValueCollection>() != null);
- if (m_values == null) {
+ if (m_values == null)
+ {
m_values = new ValueCollection(m_dictionary.Values);
}
return m_values;
@@ -66,46 +75,59 @@ namespace System.Collections.ObjectModel
#region IDictionary<TKey, TValue> Members
- public bool ContainsKey(TKey key) {
+ public bool ContainsKey(TKey key)
+ {
return m_dictionary.ContainsKey(key);
}
- ICollection<TKey> IDictionary<TKey, TValue>.Keys {
- get {
+ ICollection<TKey> IDictionary<TKey, TValue>.Keys
+ {
+ get
+ {
return Keys;
}
}
- public bool TryGetValue(TKey key, out TValue value) {
+ public bool TryGetValue(TKey key, out TValue value)
+ {
return m_dictionary.TryGetValue(key, out value);
}
- ICollection<TValue> IDictionary<TKey, TValue>.Values {
- get {
+ ICollection<TValue> IDictionary<TKey, TValue>.Values
+ {
+ get
+ {
return Values;
}
}
- public TValue this[TKey key] {
- get {
+ public TValue this[TKey key]
+ {
+ get
+ {
return m_dictionary[key];
}
}
- void IDictionary<TKey, TValue>.Add(TKey key, TValue value) {
+ void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- bool IDictionary<TKey, TValue>.Remove(TKey key) {
+ bool IDictionary<TKey, TValue>.Remove(TKey key)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
return false;
}
- TValue IDictionary<TKey, TValue>.this[TKey key] {
- get {
+ TValue IDictionary<TKey, TValue>.this[TKey key]
+ {
+ get
+ {
return m_dictionary[key];
}
- set {
+ set
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
}
@@ -114,31 +136,38 @@ namespace System.Collections.ObjectModel
#region ICollection<KeyValuePair<TKey, TValue>> Members
- public int Count {
+ public int Count
+ {
get { return m_dictionary.Count; }
}
- bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item) {
+ bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
+ {
return m_dictionary.Contains(item);
}
- void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) {
+ void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
+ {
m_dictionary.CopyTo(array, arrayIndex);
}
- bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly {
+ bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
+ {
get { return true; }
}
- void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item) {
+ void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- void ICollection<KeyValuePair<TKey, TValue>>.Clear() {
+ void ICollection<KeyValuePair<TKey, TValue>>.Clear()
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item) {
+ bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
return false;
}
@@ -147,7 +176,8 @@ namespace System.Collections.ObjectModel
#region IEnumerable<KeyValuePair<TKey, TValue>> Members
- public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
+ public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+ {
return m_dictionary.GetEnumerator();
}
@@ -155,7 +185,8 @@ namespace System.Collections.ObjectModel
#region IEnumerable Members
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
return ((IEnumerable)m_dictionary).GetEnumerator();
}
@@ -163,131 +194,170 @@ namespace System.Collections.ObjectModel
#region IDictionary Members
- private static bool IsCompatibleKey(object key) {
- if (key == null) {
+ private static bool IsCompatibleKey(object key)
+ {
+ if (key == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
return key is TKey;
}
- void IDictionary.Add(object key, object value) {
+ void IDictionary.Add(object key, object value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- void IDictionary.Clear() {
+ void IDictionary.Clear()
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- bool IDictionary.Contains(object key) {
+ bool IDictionary.Contains(object key)
+ {
return IsCompatibleKey(key) && ContainsKey((TKey)key);
}
- IDictionaryEnumerator IDictionary.GetEnumerator() {
+ IDictionaryEnumerator IDictionary.GetEnumerator()
+ {
IDictionary d = m_dictionary as IDictionary;
- if (d != null) {
+ if (d != null)
+ {
return d.GetEnumerator();
}
return new DictionaryEnumerator(m_dictionary);
}
- bool IDictionary.IsFixedSize {
+ bool IDictionary.IsFixedSize
+ {
get { return true; }
}
- bool IDictionary.IsReadOnly {
+ bool IDictionary.IsReadOnly
+ {
get { return true; }
}
- ICollection IDictionary.Keys {
- get {
+ ICollection IDictionary.Keys
+ {
+ get
+ {
return Keys;
}
}
- void IDictionary.Remove(object key) {
+ void IDictionary.Remove(object key)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- ICollection IDictionary.Values {
- get {
+ ICollection IDictionary.Values
+ {
+ get
+ {
return Values;
}
}
- object IDictionary.this[object key] {
- get {
- if (IsCompatibleKey(key)) {
+ object IDictionary.this[object key]
+ {
+ get
+ {
+ if (IsCompatibleKey(key))
+ {
return this[(TKey)key];
}
return null;
}
- set {
+ set
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
}
- void ICollection.CopyTo(Array array, int index) {
- if (array == null) {
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (array.Rank != 1) {
+ if (array.Rank != 1)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if (array.GetLowerBound(0) != 0) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
- if (index < 0 || index > array.Length) {
+ if (index < 0 || index > array.Length)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < Count) {
+ if (array.Length - index < Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
KeyValuePair<TKey, TValue>[] pairs = array as KeyValuePair<TKey, TValue>[];
- if (pairs != null) {
+ if (pairs != null)
+ {
m_dictionary.CopyTo(pairs, index);
}
- else {
+ else
+ {
DictionaryEntry[] dictEntryArray = array as DictionaryEntry[];
- if (dictEntryArray != null) {
- foreach (var item in m_dictionary) {
+ if (dictEntryArray != null)
+ {
+ foreach (var item in m_dictionary)
+ {
dictEntryArray[index++] = new DictionaryEntry(item.Key, item.Value);
}
}
- else {
+ else
+ {
object[] objects = array as object[];
- if (objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
- try {
- foreach (var item in m_dictionary) {
+ try
+ {
+ foreach (var item in m_dictionary)
+ {
objects[index++] = new KeyValuePair<TKey, TValue>(item.Key, item.Value);
}
}
- catch (ArrayTypeMismatchException) {
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- object ICollection.SyncRoot {
- get {
- if (m_syncRoot == null) {
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ if (m_syncRoot == null)
+ {
ICollection c = m_dictionary as ICollection;
- if (c != null) {
+ if (c != null)
+ {
m_syncRoot = c.SyncRoot;
}
- else {
+ else
+ {
System.Threading.Interlocked.CompareExchange<Object>(ref m_syncRoot, new Object(), null);
}
}
@@ -296,36 +366,44 @@ namespace System.Collections.ObjectModel
}
[Serializable]
- private struct DictionaryEnumerator : IDictionaryEnumerator {
+ private struct DictionaryEnumerator : IDictionaryEnumerator
+ {
private readonly IDictionary<TKey, TValue> m_dictionary;
private IEnumerator<KeyValuePair<TKey, TValue>> m_enumerator;
- public DictionaryEnumerator(IDictionary<TKey, TValue> dictionary) {
+ public DictionaryEnumerator(IDictionary<TKey, TValue> dictionary)
+ {
m_dictionary = dictionary;
m_enumerator = m_dictionary.GetEnumerator();
}
- public DictionaryEntry Entry {
+ public DictionaryEntry Entry
+ {
get { return new DictionaryEntry(m_enumerator.Current.Key, m_enumerator.Current.Value); }
}
- public object Key {
+ public object Key
+ {
get { return m_enumerator.Current.Key; }
}
- public object Value {
+ public object Value
+ {
get { return m_enumerator.Current.Value; }
}
- public object Current {
+ public object Current
+ {
get { return Entry; }
}
- public bool MoveNext() {
+ public bool MoveNext()
+ {
return m_enumerator.MoveNext();
}
- public void Reset() {
+ public void Reset()
+ {
m_enumerator.Reset();
}
}
@@ -334,14 +412,18 @@ namespace System.Collections.ObjectModel
#region IReadOnlyDictionary members
- IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys {
- get {
+ IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys
+ {
+ get
+ {
return Keys;
}
}
- IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values {
- get {
+ IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values
+ {
+ get
+ {
return Values;
}
}
@@ -351,14 +433,16 @@ namespace System.Collections.ObjectModel
[DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
- public sealed class KeyCollection : ICollection<TKey>, ICollection, IReadOnlyCollection<TKey> {
+ public sealed class KeyCollection : ICollection<TKey>, ICollection, IReadOnlyCollection<TKey>
+ {
private readonly ICollection<TKey> m_collection;
[NonSerialized]
private Object m_syncRoot;
internal KeyCollection(ICollection<TKey> collection)
{
- if (collection == null) {
+ if (collection == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
m_collection = collection;
@@ -386,11 +470,13 @@ namespace System.Collections.ObjectModel
m_collection.CopyTo(array, arrayIndex);
}
- public int Count {
+ public int Count
+ {
get { return m_collection.Count; }
}
- bool ICollection<TKey>.IsReadOnly {
+ bool ICollection<TKey>.IsReadOnly
+ {
get { return true; }
}
@@ -413,7 +499,8 @@ namespace System.Collections.ObjectModel
#region IEnumerable Members
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
return ((IEnumerable)m_collection).GetEnumerator();
}
@@ -421,22 +508,29 @@ namespace System.Collections.ObjectModel
#region ICollection Members
- void ICollection.CopyTo(Array array, int index) {
+ void ICollection.CopyTo(Array array, int index)
+ {
ReadOnlyDictionaryHelpers.CopyToNonGenericICollectionHelper<TKey>(m_collection, array, index);
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- object ICollection.SyncRoot {
- get {
- if (m_syncRoot == null) {
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ if (m_syncRoot == null)
+ {
ICollection c = m_collection as ICollection;
- if (c != null) {
+ if (c != null)
+ {
m_syncRoot = c.SyncRoot;
}
- else {
+ else
+ {
System.Threading.Interlocked.CompareExchange<Object>(ref m_syncRoot, new Object(), null);
}
}
@@ -450,14 +544,16 @@ namespace System.Collections.ObjectModel
[DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
- public sealed class ValueCollection : ICollection<TValue>, ICollection, IReadOnlyCollection<TValue> {
+ public sealed class ValueCollection : ICollection<TValue>, ICollection, IReadOnlyCollection<TValue>
+ {
private readonly ICollection<TValue> m_collection;
[NonSerialized]
private Object m_syncRoot;
internal ValueCollection(ICollection<TValue> collection)
{
- if (collection == null) {
+ if (collection == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
m_collection = collection;
@@ -485,11 +581,13 @@ namespace System.Collections.ObjectModel
m_collection.CopyTo(array, arrayIndex);
}
- public int Count {
+ public int Count
+ {
get { return m_collection.Count; }
}
- bool ICollection<TValue>.IsReadOnly {
+ bool ICollection<TValue>.IsReadOnly
+ {
get { return true; }
}
@@ -512,7 +610,8 @@ namespace System.Collections.ObjectModel
#region IEnumerable Members
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
return ((IEnumerable)m_collection).GetEnumerator();
}
@@ -520,22 +619,29 @@ namespace System.Collections.ObjectModel
#region ICollection Members
- void ICollection.CopyTo(Array array, int index) {
+ void ICollection.CopyTo(Array array, int index)
+ {
ReadOnlyDictionaryHelpers.CopyToNonGenericICollectionHelper<TValue>(m_collection, array, index);
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- object ICollection.SyncRoot {
- get {
- if (m_syncRoot == null) {
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ if (m_syncRoot == null)
+ {
ICollection c = m_collection as ICollection;
- if (c != null) {
+ if (c != null)
+ {
m_syncRoot = c.SyncRoot;
}
- else {
+ else
+ {
System.Threading.Interlocked.CompareExchange<Object>(ref m_syncRoot, new Object(), null);
}
}
@@ -555,38 +661,46 @@ namespace System.Collections.ObjectModel
// Abstracted away to avoid redundant implementations.
internal static void CopyToNonGenericICollectionHelper<T>(ICollection<T> collection, Array array, int index)
{
- if (array == null) {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (array.Rank != 1) {
+ if (array.Rank != 1)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if (array.GetLowerBound(0) != 0) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
- if (index < 0) {
+ if (index < 0)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
- if (array.Length - index < collection.Count) {
+ if (array.Length - index < collection.Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
// Easy out if the ICollection<T> implements the non-generic ICollection
ICollection nonGenericCollection = collection as ICollection;
- if (nonGenericCollection != null) {
+ if (nonGenericCollection != null)
+ {
nonGenericCollection.CopyTo(array, index);
return;
}
T[] items = array as T[];
- if (items != null) {
+ if (items != null)
+ {
collection.CopyTo(items, index);
}
- else {
+ else
+ {
//
// Catch the obvious case assignment will fail.
// We can found all possible problems by doing the check though.
@@ -595,7 +709,8 @@ namespace System.Collections.ObjectModel
//
Type targetType = array.GetType().GetElementType();
Type sourceType = typeof(T);
- if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) {
+ if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType)))
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
@@ -604,16 +719,20 @@ namespace System.Collections.ObjectModel
// widening of primitive types here.
//
object[] objects = array as object[];
- if (objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
- try {
- foreach (var item in collection) {
+ try
+ {
+ foreach (var item in collection)
+ {
objects[index++] = item;
}
}
- catch (ArrayTypeMismatchException) {
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
diff --git a/src/mscorlib/src/System/Collections/StructuralComparisons.cs b/src/mscorlib/src/System/Collections/StructuralComparisons.cs
deleted file mode 100644
index 685af59c4b..0000000000
--- a/src/mscorlib/src/System/Collections/StructuralComparisons.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// 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;
-
-namespace System.Collections {
- public static class StructuralComparisons {
-
- private static volatile IComparer s_StructuralComparer;
- private static volatile IEqualityComparer s_StructuralEqualityComparer;
-
- public static IComparer StructuralComparer {
- get {
- IComparer comparer = s_StructuralComparer;
- if (comparer == null) {
- comparer = new StructuralComparer();
- s_StructuralComparer = comparer;
- }
- return comparer;
- }
- }
-
- public static IEqualityComparer StructuralEqualityComparer {
- get {
- IEqualityComparer comparer = s_StructuralEqualityComparer;
- if (comparer == null) {
- comparer = new StructuralEqualityComparer();
- s_StructuralEqualityComparer = comparer;
- }
- return comparer;
- }
- }
- }
-
- [Serializable]
- internal class StructuralEqualityComparer : IEqualityComparer {
- public new bool Equals(Object x, Object y) {
- if (x != null) {
-
- IStructuralEquatable seObj = x as IStructuralEquatable;
-
- if (seObj != null){
- return seObj.Equals(y, this);
- }
-
- if (y != null) {
- return x.Equals(y);
- } else {
- return false;
- }
- }
- if (y != null) return false;
- return true;
- }
-
- public int GetHashCode(Object obj) {
- if (obj == null) return 0;
-
- IStructuralEquatable seObj = obj as IStructuralEquatable;
-
- if (seObj != null) {
- return seObj.GetHashCode(this);
- }
-
- return obj.GetHashCode();
- }
- }
-
- [Serializable]
- internal class StructuralComparer : IComparer {
- public int Compare(Object x, Object y) {
-
- if (x == null) return y == null ? 0 : -1;
- if (y == null) return 1;
-
- IStructuralComparable scX = x as IStructuralComparable;
-
- if (scX != null) {
- return scX.CompareTo(y, this);
- }
-
- return Comparer.Default.Compare(x, y);
- }
- }
-
-}