diff options
Diffstat (limited to 'src/mscorlib/src/System/Collections')
29 files changed, 601 insertions, 1762 deletions
diff --git a/src/mscorlib/src/System/Collections/ArrayList.cs b/src/mscorlib/src/System/Collections/ArrayList.cs index 94f4dc74e8..e7f121370b 100644 --- a/src/mscorlib/src/System/Collections/ArrayList.cs +++ b/src/mscorlib/src/System/Collections/ArrayList.cs @@ -31,9 +31,7 @@ namespace System.Collections { // of the ArrayList is automatically increased as required by reallocating the // internal array. // -#if FEATURE_CORECLR [FriendAccessAllowed] -#endif [DebuggerTypeProxy(typeof(System.Collections.ArrayList.ArrayListDebugView))] [DebuggerDisplay("Count = {Count}")] [Serializable] @@ -68,7 +66,7 @@ namespace System.Collections { // before any reallocations are required. // public ArrayList(int capacity) { - if (capacity < 0) throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", "capacity")); + if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", nameof(capacity))); Contract.EndContractBlock(); if (capacity == 0) @@ -83,7 +81,7 @@ namespace System.Collections { // public ArrayList(ICollection c) { if (c==null) - throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection")); + throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection")); Contract.EndContractBlock(); int count = c.Count; @@ -108,7 +106,7 @@ namespace System.Collections { } set { if (value < _size) { - throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity")); + throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity")); } Contract.Ensures(Capacity >= 0); Contract.EndContractBlock(); @@ -166,12 +164,12 @@ namespace System.Collections { // public virtual Object this[int index] { get { - if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); return _items[index]; } set { - if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); _items[index] = value; _version++; @@ -188,7 +186,7 @@ namespace System.Collections { // public static ArrayList Adapter(IList list) { if (list==null) - throw new ArgumentNullException("list"); + throw new ArgumentNullException(nameof(list)); Contract.Ensures(Contract.Result<ArrayList>() != null); Contract.EndContractBlock(); return new IListWrapper(list); @@ -236,9 +234,9 @@ namespace System.Collections { // public virtual int BinarySearch(int index, int count, Object value, IComparer comparer) { if (index < 0) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (count < 0) - throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (_size - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.Ensures(Contract.Result<int>() < Count); @@ -356,7 +354,7 @@ namespace System.Collections { // public static IList FixedSize(IList list) { if (list==null) - throw new ArgumentNullException("list"); + throw new ArgumentNullException(nameof(list)); Contract.Ensures(Contract.Result<IList>() != null); Contract.EndContractBlock(); return new FixedSizeList(list); @@ -367,7 +365,7 @@ namespace System.Collections { // public static ArrayList FixedSize(ArrayList list) { if (list==null) - throw new ArgumentNullException("list"); + throw new ArgumentNullException(nameof(list)); Contract.Ensures(Contract.Result<ArrayList>() != null); Contract.EndContractBlock(); return new FixedSizeArrayList(list); @@ -390,9 +388,9 @@ namespace System.Collections { // public virtual IEnumerator GetEnumerator(int index, int count) { if (index < 0) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (count < 0) - throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (_size - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.Ensures(Contract.Result<IEnumerator>() != null); @@ -425,7 +423,7 @@ namespace System.Collections { // public virtual int IndexOf(Object value, int startIndex) { if (startIndex > _size) - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.Ensures(Contract.Result<int>() < Count); Contract.EndContractBlock(); return Array.IndexOf((Array)_items, value, startIndex, _size - startIndex); @@ -442,8 +440,8 @@ namespace System.Collections { // public virtual int IndexOf(Object value, int startIndex, int count) { if (startIndex > _size) - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index")); - if (count <0 || startIndex > _size - count) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count")); + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (count <0 || startIndex > _size - count) throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count")); Contract.Ensures(Contract.Result<int>() < Count); Contract.EndContractBlock(); return Array.IndexOf((Array)_items, value, startIndex, count); @@ -455,7 +453,7 @@ namespace System.Collections { // public virtual void Insert(int index, Object value) { // Note that insertions at the end are legal. - if (index < 0 || index > _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_ArrayListInsert")); + if (index < 0 || index > _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_ArrayListInsert")); //Contract.Ensures(Count == Contract.OldValue(Count) + 1); Contract.EndContractBlock(); @@ -475,8 +473,8 @@ namespace System.Collections { // public virtual void InsertRange(int index, ICollection c) { if (c==null) - throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection")); - if (index < 0 || index > _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection")); + if (index < 0 || index > _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); //Contract.Ensures(Count == Contract.OldValue(Count) + c.Count); Contract.EndContractBlock(); @@ -522,7 +520,7 @@ namespace System.Collections { public virtual int LastIndexOf(Object value, int startIndex) { if (startIndex >= _size) - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.Ensures(Contract.Result<int>() < Count); Contract.EndContractBlock(); return LastIndexOf(value, startIndex, startIndex + 1); @@ -539,7 +537,7 @@ namespace System.Collections { // public virtual int LastIndexOf(Object value, int startIndex, int count) { if (Count != 0 && (startIndex < 0 || count < 0)) - throw new ArgumentOutOfRangeException((startIndex<0 ? "startIndex" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((startIndex<0 ? nameof(startIndex) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.Ensures(Contract.Result<int>() < Count); Contract.EndContractBlock(); @@ -547,19 +545,17 @@ namespace System.Collections { return -1; if (startIndex >= _size || count > startIndex + 1) - throw new ArgumentOutOfRangeException((startIndex>=_size ? "startIndex" : "count"), Environment.GetResourceString("ArgumentOutOfRange_BiggerThanCollection")); + throw new ArgumentOutOfRangeException((startIndex>=_size ? nameof(startIndex) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_BiggerThanCollection")); return Array.LastIndexOf((Array)_items, value, startIndex, count); } // Returns a read-only IList wrapper for the given IList. // -#if FEATURE_CORECLR [FriendAccessAllowed] -#endif public static IList ReadOnly(IList list) { if (list==null) - throw new ArgumentNullException("list"); + throw new ArgumentNullException(nameof(list)); Contract.Ensures(Contract.Result<IList>() != null); Contract.EndContractBlock(); return new ReadOnlyList(list); @@ -569,7 +565,7 @@ namespace System.Collections { // public static ArrayList ReadOnly(ArrayList list) { if (list==null) - throw new ArgumentNullException("list"); + throw new ArgumentNullException(nameof(list)); Contract.Ensures(Contract.Result<ArrayList>() != null); Contract.EndContractBlock(); return new ReadOnlyArrayList(list); @@ -591,7 +587,7 @@ namespace System.Collections { // decreased by one. // public virtual void RemoveAt(int index) { - if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.Ensures(Count >= 0); //Contract.Ensures(Count == Contract.OldValue(Count) - 1); Contract.EndContractBlock(); @@ -608,9 +604,9 @@ namespace System.Collections { // public virtual void RemoveRange(int index, int count) { if (index < 0) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (count < 0) - throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (_size - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.Ensures(Count >= 0); @@ -632,7 +628,7 @@ namespace System.Collections { // public static ArrayList Repeat(Object value, int count) { if (count < 0) - throw new ArgumentOutOfRangeException("count",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(count),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.Ensures(Contract.Result<ArrayList>() != null); Contract.EndContractBlock(); @@ -657,9 +653,9 @@ namespace System.Collections { // public virtual void Reverse(int index, int count) { if (index < 0) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (count < 0) - throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (_size - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -671,10 +667,10 @@ namespace System.Collections { // given collection. // public virtual void SetRange(int index, ICollection c) { - if (c==null) throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection")); + if (c==null) throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection")); Contract.EndContractBlock(); int count = c.Count; - if (index < 0 || index > _size - count) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (index < 0 || index > _size - count) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); if (count > 0) { c.CopyTo(_items, index); @@ -684,7 +680,7 @@ namespace System.Collections { public virtual ArrayList GetRange(int index, int count) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (_size - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.Ensures(Contract.Result<ArrayList>() != null); @@ -716,9 +712,9 @@ namespace System.Collections { // public virtual void Sort(int index, int count, IComparer comparer) { if (index < 0) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (count < 0) - throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (_size - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -729,10 +725,9 @@ namespace System.Collections { // Returns a thread-safe wrapper around an IList. // - [HostProtection(Synchronization=true)] public static IList Synchronized(IList list) { if (list==null) - throw new ArgumentNullException("list"); + throw new ArgumentNullException(nameof(list)); Contract.Ensures(Contract.Result<IList>() != null); Contract.EndContractBlock(); return new SyncIList(list); @@ -740,10 +735,9 @@ namespace System.Collections { // Returns a thread-safe wrapper around a ArrayList. // - [HostProtection(Synchronization=true)] public static ArrayList Synchronized(ArrayList list) { if (list==null) - throw new ArgumentNullException("list"); + throw new ArgumentNullException(nameof(list)); Contract.Ensures(Contract.Result<ArrayList>() != null); Contract.EndContractBlock(); return new SyncArrayList(list); @@ -764,10 +758,9 @@ namespace System.Collections { // downcasting all elements. This copy may fail and is an O(n) operation. // Internally, this implementation calls Array.Copy. // - [SecuritySafeCritical] public virtual Array ToArray(Type type) { if (type==null) - throw new ArgumentNullException("type"); + throw new ArgumentNullException(nameof(type)); Contract.Ensures(Contract.Result<Array>() != null); Contract.EndContractBlock(); Array array = Array.UnsafeCreateInstance(type, _size); @@ -804,7 +797,7 @@ namespace System.Collections { public override int Capacity { get { return _list.Count; } set { - if (value < Count) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity")); + if (value < Count) throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity")); Contract.EndContractBlock(); } } @@ -854,7 +847,7 @@ namespace System.Collections { public override int BinarySearch(int index, int count, Object value, IComparer comparer) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (this.Count - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -906,11 +899,11 @@ namespace System.Collections { public override void CopyTo(int index, Array array, int arrayIndex, int count) { if (array==null) - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); if (index < 0 || arrayIndex < 0) - throw new ArgumentOutOfRangeException((index < 0) ? "index" : "arrayIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index < 0) ? nameof(index) : nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if( count < 0) - throw new ArgumentOutOfRangeException( "count" , Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException( nameof(count) , Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (array.Length - arrayIndex < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); if (array.Rank != 1) @@ -930,7 +923,7 @@ namespace System.Collections { public override IEnumerator GetEnumerator(int index, int count) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); if (_list.Count - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); @@ -948,8 +941,8 @@ namespace System.Collections { } public override int IndexOf(Object value, int startIndex, int count) { - if (startIndex < 0 || startIndex > this.Count) throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index")); - if (count < 0 || startIndex > this.Count - count) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count")); + if (startIndex < 0 || startIndex > this.Count) throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (count < 0 || startIndex > this.Count - count) throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count")); Contract.EndContractBlock(); int endIndex = startIndex + count; @@ -973,8 +966,8 @@ namespace System.Collections { public override void InsertRange(int index, ICollection c) { if (c==null) - throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection")); - if (index < 0 || index > this.Count) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection")); + if (index < 0 || index > this.Count) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); if( c.Count > 0) { @@ -1009,8 +1002,8 @@ namespace System.Collections { if (_list.Count == 0) return -1; - if (startIndex < 0 || startIndex >= _list.Count) throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index")); - if (count < 0 || count > startIndex + 1) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count")); + if (startIndex < 0 || startIndex >= _list.Count) throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (count < 0 || count > startIndex + 1) throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count")); int endIndex = startIndex - count + 1; if (value == null) { @@ -1039,7 +1032,7 @@ namespace System.Collections { public override void RemoveRange(int index, int count) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); if (_list.Count - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); @@ -1055,7 +1048,7 @@ namespace System.Collections { public override void Reverse(int index, int count) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); if (_list.Count - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); @@ -1073,12 +1066,12 @@ namespace System.Collections { public override void SetRange(int index, ICollection c) { if (c==null) { - throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection")); + throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection")); } Contract.EndContractBlock(); if (index < 0 || index > _list.Count - c.Count) { - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); } if( c.Count > 0) { @@ -1092,7 +1085,7 @@ namespace System.Collections { public override ArrayList GetRange(int index, int count) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); if (_list.Count - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); @@ -1101,7 +1094,7 @@ namespace System.Collections { public override void Sort(int index, int count, IComparer comparer) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); if (_list.Count - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); @@ -1122,11 +1115,10 @@ namespace System.Collections { return array; } - [SecuritySafeCritical] public override Array ToArray(Type type) { if (type==null) - throw new ArgumentNullException("type"); + throw new ArgumentNullException(nameof(type)); Contract.EndContractBlock(); Array array = Array.UnsafeCreateInstance(type, _list.Count); _list.CopyTo(array, 0); @@ -1806,7 +1798,7 @@ namespace System.Collections { public override ArrayList GetRange(int index, int count) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (Count - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -2062,7 +2054,7 @@ namespace System.Collections { public override ArrayList GetRange(int index, int count) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (Count - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -2191,7 +2183,7 @@ namespace System.Collections { public override void AddRange(ICollection c) { if( c == null ) { - throw new ArgumentNullException("c"); + throw new ArgumentNullException(nameof(c)); } Contract.EndContractBlock(); @@ -2207,7 +2199,7 @@ namespace System.Collections { // Other overloads with automatically work public override int BinarySearch(int index, int count, Object value, IComparer comparer) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (_baseSize - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -2224,7 +2216,7 @@ namespace System.Collections { } set { - if (value < Count) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity")); + if (value < Count) throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity")); Contract.EndContractBlock(); } } @@ -2265,11 +2257,11 @@ namespace System.Collections { public override void CopyTo(Array array, int index) { if (array==null) - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); if (array.Rank != 1) throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported")); if (index < 0) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (array.Length - index < _baseSize) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -2280,11 +2272,11 @@ namespace System.Collections { public override void CopyTo(int index, Array array, int arrayIndex, int count) { if (array==null) - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); if (array.Rank != 1) throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported")); if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (array.Length - arrayIndex < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); if (_baseSize - index < count) @@ -2320,7 +2312,7 @@ namespace System.Collections { public override IEnumerator GetEnumerator(int index, int count) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (_baseSize - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -2331,7 +2323,7 @@ namespace System.Collections { public override ArrayList GetRange(int index, int count) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (_baseSize - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -2356,9 +2348,9 @@ namespace System.Collections { public override int IndexOf(Object value, int startIndex) { if (startIndex < 0) - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (startIndex > _baseSize) - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); InternalUpdateRange(); @@ -2369,10 +2361,10 @@ namespace System.Collections { public override int IndexOf(Object value, int startIndex, int count) { if (startIndex < 0 || startIndex > _baseSize) - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index")); if (count < 0 || (startIndex > _baseSize - count)) - throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count")); + throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count")); Contract.EndContractBlock(); InternalUpdateRange(); @@ -2382,7 +2374,7 @@ namespace System.Collections { } public override void Insert(int index, Object value) { - if (index < 0 || index > _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (index < 0 || index > _baseSize) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); InternalUpdateRange(); @@ -2392,9 +2384,9 @@ namespace System.Collections { } public override void InsertRange(int index, ICollection c) { - if (index < 0 || index > _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (index < 0 || index > _baseSize) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); if( c == null) { - throw new ArgumentNullException("c"); + throw new ArgumentNullException(nameof(c)); } Contract.EndContractBlock(); @@ -2426,9 +2418,9 @@ namespace System.Collections { return -1; if (startIndex >= _baseSize) - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index")); if (startIndex < 0) - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); int i = _baseList.LastIndexOf(value, _baseIndex + startIndex, count); if (i >= 0) return i - _baseIndex; @@ -2438,7 +2430,7 @@ namespace System.Collections { // Don't need to override Remove public override void RemoveAt(int index) { - if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); InternalUpdateRange(); @@ -2449,7 +2441,7 @@ namespace System.Collections { public override void RemoveRange(int index, int count) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (_baseSize - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -2466,7 +2458,7 @@ namespace System.Collections { public override void Reverse(int index, int count) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (_baseSize - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -2479,7 +2471,7 @@ namespace System.Collections { [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. public override void SetRange(int index, ICollection c) { InternalUpdateRange(); - if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); _baseList.SetRange(_baseIndex + index, c); if( c.Count > 0) { InternalUpdateVersion(); @@ -2488,7 +2480,7 @@ namespace System.Collections { public override void Sort(int index, int count, IComparer comparer) { if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (_baseSize - index < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -2501,12 +2493,12 @@ namespace System.Collections { public override Object this[int index] { get { InternalUpdateRange(); - if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); return _baseList[_baseIndex + index]; } set { InternalUpdateRange(); - if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); _baseList[_baseIndex + index] = value; InternalUpdateVersion(); } @@ -2519,10 +2511,9 @@ namespace System.Collections { return array; } - [SecuritySafeCritical] public override Array ToArray(Type type) { if (type==null) - throw new ArgumentNullException("type"); + throw new ArgumentNullException(nameof(type)); Contract.EndContractBlock(); InternalUpdateRange(); @@ -2619,7 +2610,7 @@ namespace System.Collections { public ArrayListDebugView( ArrayList arrayList) { if( arrayList == null) - throw new ArgumentNullException("arrayList"); + throw new ArgumentNullException(nameof(arrayList)); this.arrayList = arrayList; } diff --git a/src/mscorlib/src/System/Collections/BitArray.cs b/src/mscorlib/src/System/Collections/BitArray.cs deleted file mode 100644 index 2f565f83af..0000000000 --- a/src/mscorlib/src/System/Collections/BitArray.cs +++ /dev/null @@ -1,524 +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: The BitArray class manages a compact array of bit values. -** -** -=============================================================================*/ -namespace System.Collections { - - using System; - using System.Security.Permissions; - using System.Diagnostics.Contracts; - // A vector of bits. Use this to store bits efficiently, without having to do bit - // shifting yourself. -[System.Runtime.InteropServices.ComVisible(true)] - [Serializable()] public sealed class BitArray : ICollection, ICloneable { - private BitArray() { - } - - /*========================================================================= - ** Allocates space to hold length bit values. All of the values in the bit - ** array are set to false. - ** - ** Exceptions: ArgumentException if length < 0. - =========================================================================*/ - public BitArray(int length) - : this(length, false) { - } - - /*========================================================================= - ** Allocates space to hold length bit values. All of the values in the bit - ** array are set to defaultValue. - ** - ** Exceptions: ArgumentOutOfRangeException if length < 0. - =========================================================================*/ - public BitArray(int length, bool defaultValue) { - if (length < 0) { - throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - } - Contract.EndContractBlock(); - - m_array = new int[GetArrayLength(length, BitsPerInt32)]; - m_length = length; - - int fillValue = defaultValue ? unchecked(((int)0xffffffff)) : 0; - for (int i = 0; i < m_array.Length; i++) { - m_array[i] = fillValue; - } - - _version = 0; - } - - /*========================================================================= - ** Allocates space to hold the bit values in bytes. bytes[0] represents - ** bits 0 - 7, bytes[1] represents bits 8 - 15, etc. The LSB of each byte - ** represents the lowest index value; bytes[0] & 1 represents bit 0, - ** bytes[0] & 2 represents bit 1, bytes[0] & 4 represents bit 2, etc. - ** - ** Exceptions: ArgumentException if bytes == null. - =========================================================================*/ - public BitArray(byte[] bytes) { - if (bytes == null) { - throw new ArgumentNullException(nameof(bytes)); - } - Contract.EndContractBlock(); - // this value is chosen to prevent overflow when computing m_length. - // m_length is of type int32 and is exposed as a property, so - // type of m_length can't be changed to accommodate. - if (bytes.Length > Int32.MaxValue / BitsPerByte) { - throw new ArgumentException(Environment.GetResourceString("Argument_ArrayTooLarge", BitsPerByte), nameof(bytes)); - } - - m_array = new int[GetArrayLength(bytes.Length, BytesPerInt32)]; - m_length = bytes.Length * BitsPerByte; - - int i = 0; - int j = 0; - while (bytes.Length - j >= 4) { - m_array[i++] = (bytes[j] & 0xff) | - ((bytes[j + 1] & 0xff) << 8) | - ((bytes[j + 2] & 0xff) << 16) | - ((bytes[j + 3] & 0xff) << 24); - j += 4; - } - - Contract.Assert(bytes.Length - j >= 0, "BitArray byteLength problem"); - Contract.Assert(bytes.Length - j < 4, "BitArray byteLength problem #2"); - - switch (bytes.Length - j) { - case 3: - m_array[i] = ((bytes[j + 2] & 0xff) << 16); - goto case 2; - // fall through - case 2: - m_array[i] |= ((bytes[j + 1] & 0xff) << 8); - goto case 1; - // fall through - case 1: - m_array[i] |= (bytes[j] & 0xff); - break; - } - - _version = 0; - } - - public BitArray(bool[] values) { - if (values == null) { - throw new ArgumentNullException(nameof(values)); - } - Contract.EndContractBlock(); - - m_array = new int[GetArrayLength(values.Length, BitsPerInt32)]; - m_length = values.Length; - - for (int i = 0;i<values.Length;i++) { - if (values[i]) - m_array[i/32] |= (1 << (i%32)); - } - - _version = 0; - - } - - /*========================================================================= - ** Allocates space to hold the bit values in values. values[0] represents - ** bits 0 - 31, values[1] represents bits 32 - 63, etc. The LSB of each - ** integer represents the lowest index value; values[0] & 1 represents bit - ** 0, values[0] & 2 represents bit 1, values[0] & 4 represents bit 2, etc. - ** - ** Exceptions: ArgumentException if values == null. - =========================================================================*/ - public BitArray(int[] values) { - if (values == null) { - throw new ArgumentNullException(nameof(values)); - } - Contract.EndContractBlock(); - // this value is chosen to prevent overflow when computing m_length - if (values.Length > Int32.MaxValue / BitsPerInt32) { - throw new ArgumentException(Environment.GetResourceString("Argument_ArrayTooLarge", BitsPerInt32), nameof(values)); - } - - m_array = new int[values.Length]; - m_length = values.Length * BitsPerInt32; - - Array.Copy(values, m_array, values.Length); - - _version = 0; - } - - /*========================================================================= - ** Allocates a new BitArray with the same length and bit values as bits. - ** - ** Exceptions: ArgumentException if bits == null. - =========================================================================*/ - public BitArray(BitArray bits) { - if (bits == null) { - throw new ArgumentNullException(nameof(bits)); - } - Contract.EndContractBlock(); - - int arrayLength = GetArrayLength(bits.m_length, BitsPerInt32); - m_array = new int[arrayLength]; - m_length = bits.m_length; - - Array.Copy(bits.m_array, m_array, arrayLength); - - _version = bits._version; - } - - public bool this[int index] { - get { - return Get(index); - } - set { - Set(index,value); - } - } - - /*========================================================================= - ** Returns the bit value at position index. - ** - ** Exceptions: ArgumentOutOfRangeException if index < 0 or - ** index >= GetLength(). - =========================================================================*/ - public bool Get(int index) { - if (index < 0 || index >= Length) { - throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); - } - Contract.EndContractBlock(); - - return (m_array[index / 32] & (1 << (index % 32))) != 0; - } - - /*========================================================================= - ** Sets the bit value at position index to value. - ** - ** Exceptions: ArgumentOutOfRangeException if index < 0 or - ** index >= GetLength(). - =========================================================================*/ - public void Set(int index, bool value) { - if (index < 0 || index >= Length) { - throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); - } - Contract.EndContractBlock(); - - if (value) { - m_array[index / 32] |= (1 << (index % 32)); - } else { - m_array[index / 32] &= ~(1 << (index % 32)); - } - - _version++; - } - - /*========================================================================= - ** Sets all the bit values to value. - =========================================================================*/ - public void SetAll(bool value) { - int fillValue = value ? unchecked(((int)0xffffffff)) : 0; - int ints = GetArrayLength(m_length, BitsPerInt32); - for (int i = 0; i < ints; i++) { - m_array[i] = fillValue; - } - - _version++; - } - - /*========================================================================= - ** Returns a reference to the current instance ANDed with value. - ** - ** Exceptions: ArgumentException if value == null or - ** value.Length != this.Length. - =========================================================================*/ - public BitArray And(BitArray value) { - if (value==null) - throw new ArgumentNullException(nameof(value)); - if (Length != value.Length) - throw new ArgumentException(Environment.GetResourceString("Arg_ArrayLengthsDiffer")); - Contract.EndContractBlock(); - - int ints = GetArrayLength(m_length, BitsPerInt32); - for (int i = 0; i < ints; i++) { - m_array[i] &= value.m_array[i]; - } - - _version++; - return this; - } - - /*========================================================================= - ** Returns a reference to the current instance ORed with value. - ** - ** Exceptions: ArgumentException if value == null or - ** value.Length != this.Length. - =========================================================================*/ - public BitArray Or(BitArray value) { - if (value==null) - throw new ArgumentNullException(nameof(value)); - if (Length != value.Length) - throw new ArgumentException(Environment.GetResourceString("Arg_ArrayLengthsDiffer")); - Contract.EndContractBlock(); - - int ints = GetArrayLength(m_length, BitsPerInt32); - for (int i = 0; i < ints; i++) { - m_array[i] |= value.m_array[i]; - } - - _version++; - return this; - } - - /*========================================================================= - ** Returns a reference to the current instance XORed with value. - ** - ** Exceptions: ArgumentException if value == null or - ** value.Length != this.Length. - =========================================================================*/ - public BitArray Xor(BitArray value) { - if (value==null) - throw new ArgumentNullException(nameof(value)); - if (Length != value.Length) - throw new ArgumentException(Environment.GetResourceString("Arg_ArrayLengthsDiffer")); - Contract.EndContractBlock(); - - int ints = GetArrayLength(m_length, BitsPerInt32); - for (int i = 0; i < ints; i++) { - m_array[i] ^= value.m_array[i]; - } - - _version++; - return this; - } - - /*========================================================================= - ** Inverts all the bit values. On/true bit values are converted to - ** off/false. Off/false bit values are turned on/true. The current instance - ** is updated and returned. - =========================================================================*/ - public BitArray Not() { - int ints = GetArrayLength(m_length, BitsPerInt32); - for (int i = 0; i < ints; i++) { - m_array[i] = ~m_array[i]; - } - - _version++; - return this; - } - - public int Length { - get { - Contract.Ensures(Contract.Result<int>() >= 0); - return m_length; - } - set { - if (value < 0) { - throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - } - Contract.EndContractBlock(); - - int newints = GetArrayLength(value, BitsPerInt32); - if (newints > m_array.Length || newints + _ShrinkThreshold < m_array.Length) { - // grow or shrink (if wasting more than _ShrinkThreshold ints) - int[] newarray = new int[newints]; - Array.Copy(m_array, newarray, newints > m_array.Length ? m_array.Length : newints); - m_array = newarray; - } - - if (value > m_length) { - // clear high bit values in the last int - int last = GetArrayLength(m_length, BitsPerInt32) - 1; - int bits = m_length % 32; - if (bits > 0) { - m_array[last] &= (1 << bits) - 1; - } - - // clear remaining int values - Array.Clear(m_array, last + 1, newints - last - 1); - } - - m_length = value; - _version++; - } - } - - // ICollection implementation - public void CopyTo(Array array, int index) - { - if (array == null) - throw new ArgumentNullException(nameof(array)); - - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - - if (array.Rank != 1) - throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"), nameof(array)); - - Contract.EndContractBlock(); - - if (array is int[]) - { - Array.Copy(m_array, 0, array, index, GetArrayLength(m_length, BitsPerInt32)); - } - else if (array is byte[]) - { - int arrayLength = GetArrayLength(m_length, BitsPerByte); - if ((array.Length - index) < arrayLength) - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); - - byte [] b = (byte[])array; - for (int i = 0; i < arrayLength; i++) - b[index + i] = (byte)((m_array[i/4] >> ((i%4)*8)) & 0x000000FF); // Shift to bring the required byte to LSB, then mask - } - else if (array is bool[]) - { - if (array.Length - index < m_length) - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); - - bool [] b = (bool[])array; - for (int i = 0;i<m_length;i++) - b[index + i] = ((m_array[i/32] >> (i%32)) & 0x00000001) != 0; - } - else - throw new ArgumentException(Environment.GetResourceString("Arg_BitArrayTypeUnsupported"), nameof(array)); - } - - public int Count - { - get - { - Contract.Ensures(Contract.Result<int>() >= 0); - - return m_length; - } - } - - public Object Clone() - { - Contract.Ensures(Contract.Result<Object>() != null); - Contract.Ensures(((BitArray)Contract.Result<Object>()).Length == this.Length); - - return new BitArray(this); - } - - public Object SyncRoot - { - get - { - if( _syncRoot == null) { - System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null); - } - return _syncRoot; - } - } - - public bool IsReadOnly - { - get - { - return false; - } - } - - public bool IsSynchronized - { - get - { - return false; - } - } - - public IEnumerator GetEnumerator() - { - return new BitArrayEnumeratorSimple(this); - } - - // XPerY=n means that n Xs can be stored in 1 Y. - private const int BitsPerInt32 = 32; - private const int BytesPerInt32 = 4; - private const int BitsPerByte = 8; - - /// <summary> - /// Used for conversion between different representations of bit array. - /// Returns (n+(div-1))/div, rearranged to avoid arithmetic overflow. - /// For example, in the bit to int case, the straightforward calc would - /// be (n+31)/32, but that would cause overflow. So instead it's - /// rearranged to ((n-1)/32) + 1, with special casing for 0. - /// - /// Usage: - /// GetArrayLength(77, BitsPerInt32): returns how many ints must be - /// allocated to store 77 bits. - /// </summary> - /// <param name="n"></param> - /// <param name="div">use a conversion constant, e.g. BytesPerInt32 to get - /// how many ints are required to store n bytes</param> - /// <returns></returns> - private static int GetArrayLength(int n, int div) { - Contract.Assert(div > 0, "GetArrayLength: div arg must be greater than 0"); - return n > 0 ? (((n - 1) / div) + 1) : 0; - } - - [Serializable] - private class BitArrayEnumeratorSimple : IEnumerator, ICloneable - { - private BitArray bitarray; - private int index; - private int version; - private bool currentElement; - - internal BitArrayEnumeratorSimple(BitArray bitarray) { - this.bitarray = bitarray; - this.index = -1; - version = bitarray._version; - } - - public Object Clone() { - return MemberwiseClone(); - } - - public virtual bool MoveNext() { - if (version != bitarray._version) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion)); - if (index < (bitarray.Count-1)) { - index++; - currentElement = bitarray.Get(index); - return true; - } - else - index = bitarray.Count; - - return false; - } - - public virtual Object Current { - get { - if (index == -1) - throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted)); - if (index >= bitarray.Count) - throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded)); - return currentElement; - } - } - - public void Reset() { - if (version != bitarray._version) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion)); - index = -1; - } - } - - private int[] m_array; - private int m_length; - private int _version; - [NonSerialized] - private Object _syncRoot; - - private const int _ShrinkThreshold = 256; - } - -} diff --git a/src/mscorlib/src/System/Collections/CollectionBase.cs b/src/mscorlib/src/System/Collections/CollectionBase.cs index 1bb08af27a..ae0c0d302d 100644 --- a/src/mscorlib/src/System/Collections/CollectionBase.cs +++ b/src/mscorlib/src/System/Collections/CollectionBase.cs @@ -62,7 +62,7 @@ namespace System.Collections { public void RemoveAt(int index) { if (index < 0 || index >= Count) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); Object temp = InnerList[index]; OnValidate(temp); @@ -101,13 +101,13 @@ namespace System.Collections { Object IList.this[int index] { get { if (index < 0 || index >= Count) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); return InnerList[index]; } set { if (index < 0 || index >= Count) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); OnValidate(value); Object temp = InnerList[index]; @@ -163,7 +163,7 @@ namespace System.Collections { void IList.Insert(int index, Object value) { if (index < 0 || index > Count) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); OnValidate(value); OnInsert(index, value); @@ -194,7 +194,7 @@ namespace System.Collections { } protected virtual void OnValidate(Object value) { - if (value == null) throw new ArgumentNullException("value"); + if (value == null) throw new ArgumentNullException(nameof(value)); Contract.EndContractBlock(); } diff --git a/src/mscorlib/src/System/Collections/Comparer.cs b/src/mscorlib/src/System/Collections/Comparer.cs index 11e26252a8..0e3c78b529 100644 --- a/src/mscorlib/src/System/Collections/Comparer.cs +++ b/src/mscorlib/src/System/Collections/Comparer.cs @@ -36,7 +36,7 @@ namespace System.Collections { public Comparer(CultureInfo culture) { if (culture==null) { - throw new ArgumentNullException("culture"); + throw new ArgumentNullException(nameof(culture)); } Contract.EndContractBlock(); m_compareInfo = culture.CompareInfo; @@ -83,10 +83,9 @@ namespace System.Collections { throw new ArgumentException(Environment.GetResourceString("Argument_ImplementIComparable")); } - [System.Security.SecurityCritical] // auto-generated_required public void GetObjectData(SerializationInfo info, StreamingContext context) { if (info==null) { - throw new ArgumentNullException("info"); + throw new ArgumentNullException(nameof(info)); } Contract.EndContractBlock(); diff --git a/src/mscorlib/src/System/Collections/CompatibleComparer.cs b/src/mscorlib/src/System/Collections/CompatibleComparer.cs index 85e6c3f0f3..e5d3961245 100644 --- a/src/mscorlib/src/System/Collections/CompatibleComparer.cs +++ b/src/mscorlib/src/System/Collections/CompatibleComparer.cs @@ -39,7 +39,7 @@ namespace System.Collections { public int GetHashCode(Object obj) { if( obj == null) { - throw new ArgumentNullException("obj"); + throw new ArgumentNullException(nameof(obj)); } Contract.EndContractBlock(); diff --git a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs index d805dc8be7..c1a6f7564c 100644 --- a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs +++ b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs @@ -28,7 +28,6 @@ using System.Security.Permissions; namespace System.Collections.Concurrent { - /// <summary> /// Represents a thread-safe collection of keys and values. /// </summary> @@ -38,13 +37,9 @@ namespace System.Collections.Concurrent /// All public and protected members of <see cref="ConcurrentDictionary{TKey,TValue}"/> are thread-safe and may be used /// concurrently from multiple threads. /// </remarks> -#if !FEATURE_CORECLR - [Serializable] -#endif [ComVisible(false)] [DebuggerTypeProxy(typeof(Mscorlib_DictionaryDebugView<,>))] [DebuggerDisplay("Count = {Count}")] - [HostProtection(Synchronization = true, ExternalThreading = true)] public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue> { /// <summary> @@ -68,41 +63,20 @@ namespace System.Collections.Concurrent m_comparer = comparer; } } -#if !FEATURE_CORECLR - [NonSerialized] -#endif + 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; -#if !FEATURE_CORECLR - [NonSerialized] -#endif private readonly bool m_growLockArray; // Whether to dynamically increase the size of the striped lock // How many times we resized becaused of collisions. // This is used to make sure we don't resize the dictionary because of multi-threaded Add() calls // that generate collisions. Whenever a GrowTable() should be the only place that changes this -#if !FEATURE_CORECLR - // The field should be have been marked as NonSerialized but because we shipped it without that attribute in 4.5.1. - // we can't add it back without breaking compat. To maximize compat we are going to keep the OptionalField attribute - // This will prevent cases where the field was not serialized. - [OptionalField] -#endif private int m_keyRehashCount; -#if !FEATURE_CORECLR - [NonSerialized] -#endif private int m_budget; // The maximum number of elements per lock before a resize operation is triggered -#if !FEATURE_CORECLR // These fields are not used in CoreCLR - private KeyValuePair<TKey, TValue>[] m_serializationArray; // Used for custom serialization - - private int m_serializationConcurrencyLevel; // used to save the concurrency level in serialization - - private int m_serializationCapacity; // used to save the capacity in serialization -#endif // The default concurrency level is DEFAULT_CONCURRENCY_MULTIPLIER * #CPUs. The higher the // DEFAULT_CONCURRENCY_MULTIPLIER, the more concurrent writes can take place without interference // and blocking, but also the more expensive operations that require all locks become (e.g. table @@ -229,7 +203,7 @@ namespace System.Collections.Concurrent public ConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer) : this(comparer) { - if (collection == null) throw new ArgumentNullException("collection"); + if (collection == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection); InitializeFromCollection(collection); } @@ -259,8 +233,8 @@ namespace System.Collections.Concurrent int concurrencyLevel, IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer) : this(concurrencyLevel, DEFAULT_CAPACITY, false, comparer) { - if (collection == null) throw new ArgumentNullException("collection"); - if (comparer == null) throw new ArgumentNullException("comparer"); + if (collection == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection); + if (comparer == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.comparer); InitializeFromCollection(collection); } @@ -270,11 +244,11 @@ namespace System.Collections.Concurrent TValue dummy; foreach (KeyValuePair<TKey, TValue> pair in collection) { - if (pair.Key == null) throw new ArgumentNullException("key"); + if (pair.Key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); if (!TryAddInternal(pair.Key, pair.Value, false, false, out dummy)) { - throw new ArgumentException(GetResource("ConcurrentDictionary_SourceContainsDuplicateKeys")); + ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_SourceContainsDuplicateKeys); } } @@ -312,13 +286,13 @@ namespace System.Collections.Concurrent { if (concurrencyLevel < 1) { - throw new ArgumentOutOfRangeException("concurrencyLevel", GetResource("ConcurrentDictionary_ConcurrencyLevelMustBePositive")); + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.concurrencyLevel, ExceptionResource.ConcurrentDictionary_ConcurrencyLevelMustBePositive); } if (capacity < 0) { - throw new ArgumentOutOfRangeException("capacity", GetResource("ConcurrentDictionary_CapacityMustNotBeNegative")); + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ConcurrentDictionary_CapacityMustNotBeNegative); } - if (comparer == null) throw new ArgumentNullException("comparer"); + if (comparer == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.comparer); // The capacity should be at least as large as the concurrency level. Otherwise, we would have locks that don't guard // any buckets. @@ -358,7 +332,7 @@ namespace System.Collections.Concurrent /// contains too many elements.</exception> public bool TryAdd(TKey key, TValue value) { - if (key == null) throw new ArgumentNullException("key"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); TValue dummy; return TryAddInternal(key, value, false, true, out dummy); } @@ -375,7 +349,7 @@ namespace System.Collections.Concurrent /// (Nothing in Visual Basic).</exception> public bool ContainsKey(TKey key) { - if (key == null) throw new ArgumentNullException("key"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); TValue throwAwayValue; return TryGetValue(key, out throwAwayValue); @@ -395,7 +369,7 @@ namespace System.Collections.Concurrent /// (Nothing in Visual Basic).</exception> public bool TryRemove(TKey key, out TValue value) { - if (key == null) throw new ArgumentNullException("key"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); return TryRemoveInternal(key, out value, false, default(TValue)); } @@ -486,7 +460,7 @@ namespace System.Collections.Concurrent [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread safety")] public bool TryGetValue(TKey key, out TValue value) { - if (key == null) throw new ArgumentNullException("key"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); int bucketNo, lockNoUnused; @@ -531,7 +505,7 @@ namespace System.Collections.Concurrent [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread safety")] public bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue) { - if (key == null) throw new ArgumentNullException("key"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); IEqualityComparer<TValue> valueComparer = EqualityComparer<TValue>.Default; @@ -642,8 +616,8 @@ namespace System.Collections.Concurrent [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "ConcurrencyCop just doesn't know about these locks")] void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int index) { - if (array == null) throw new ArgumentNullException("array"); - if (index < 0) throw new ArgumentOutOfRangeException("index", GetResource("ConcurrentDictionary_IndexIsNegative")); + if (array == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); + if (index < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ConcurrentDictionary_IndexIsNegative); int locksAcquired = 0; try @@ -659,7 +633,7 @@ namespace System.Collections.Concurrent if (array.Length - count < index || count < 0) //"count" itself or "count + index" can overflow { - throw new ArgumentException(GetResource("ConcurrentDictionary_ArrayNotLargeEnough")); + ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_ArrayNotLargeEnough); } CopyToPairs(array, index); @@ -803,11 +777,6 @@ namespace System.Collections.Concurrent bool resizeDesired = false; bool lockTaken = false; -#if FEATURE_RANDOMIZED_STRING_HASHING -#if !FEATURE_CORECLR - bool resizeDueToCollisions = false; -#endif // !FEATURE_CORECLR -#endif try { @@ -821,12 +790,6 @@ namespace System.Collections.Concurrent continue; } -#if FEATURE_RANDOMIZED_STRING_HASHING -#if !FEATURE_CORECLR - int collisionCount = 0; -#endif // !FEATURE_CORECLR -#endif - // Try to find this key in the bucket Node prev = null; for (Node node = tables.m_buckets[bucketNo]; node != null; node = node.m_next) @@ -864,23 +827,7 @@ namespace System.Collections.Concurrent return false; } prev = node; - -#if FEATURE_RANDOMIZED_STRING_HASHING -#if !FEATURE_CORECLR - collisionCount++; -#endif // !FEATURE_CORECLR -#endif - } - -#if FEATURE_RANDOMIZED_STRING_HASHING -#if !FEATURE_CORECLR - if(collisionCount > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(comparer)) - { - resizeDesired = true; - resizeDueToCollisions = true; } -#endif // !FEATURE_CORECLR -#endif // The key was not found in the bucket. Insert the key-value pair. Volatile.Write<Node>(ref tables.m_buckets[bucketNo], new Node(key, value, hashcode, tables.m_buckets[bucketNo])); @@ -916,16 +863,7 @@ namespace System.Collections.Concurrent if (resizeDesired) { #if FEATURE_RANDOMIZED_STRING_HASHING -#if !FEATURE_CORECLR - if (resizeDueToCollisions) - { - GrowTable(tables, (IEqualityComparer<TKey>)HashHelpers.GetRandomizedEqualityComparer(comparer), true, m_keyRehashCount); - } - else -#endif // !FEATURE_CORECLR - { - GrowTable(tables, tables.m_comparer, false, m_keyRehashCount); - } + GrowTable(tables, tables.m_comparer, false, m_keyRehashCount); #else GrowTable(tables, tables.m_comparer, false, m_keyRehashCount); #endif @@ -956,13 +894,13 @@ namespace System.Collections.Concurrent TValue value; if (!TryGetValue(key, out value)) { - throw new KeyNotFoundException(); + ThrowHelper.ThrowKeyNotFoundException(); } return value; } set { - if (key == null) throw new ArgumentNullException("key"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); TValue dummy; TryAddInternal(key, value, true, true, out dummy); } @@ -1026,8 +964,8 @@ namespace System.Collections.Concurrent /// if the key was not in the dictionary.</returns> public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory) { - if (key == null) throw new ArgumentNullException("key"); - if (valueFactory == null) throw new ArgumentNullException("valueFactory"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); + if (valueFactory == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.valueFactory); TValue resultingValue; if (TryGetValue(key, out resultingValue)) @@ -1052,7 +990,7 @@ namespace System.Collections.Concurrent /// key is already in the dictionary, or the new value if the key was not in the dictionary.</returns> public TValue GetOrAdd(TKey key, TValue value) { - if (key == null) throw new ArgumentNullException("key"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); TValue resultingValue; TryAddInternal(key, value, false, true, out resultingValue); @@ -1080,9 +1018,9 @@ namespace System.Collections.Concurrent /// absent) or the result of updateValueFactory (if the key was present).</returns> public TValue AddOrUpdate(TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory) { - if (key == null) throw new ArgumentNullException("key"); - if (addValueFactory == null) throw new ArgumentNullException("addValueFactory"); - if (updateValueFactory == null) throw new ArgumentNullException("updateValueFactory"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); + if (addValueFactory == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.addValueFactory); + if (updateValueFactory == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.updateValueFactory); TValue newValue, resultingValue; while (true) @@ -1127,8 +1065,8 @@ namespace System.Collections.Concurrent /// absent) or the result of updateValueFactory (if the key was present).</returns> public TValue AddOrUpdate(TKey key, TValue addValue, Func<TKey, TValue, TValue> updateValueFactory) { - if (key == null) throw new ArgumentNullException("key"); - if (updateValueFactory == null) throw new ArgumentNullException("updateValueFactory"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); + if (updateValueFactory == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.updateValueFactory); TValue newValue, resultingValue; while (true) { @@ -1207,7 +1145,7 @@ namespace System.Collections.Concurrent { if (!TryAdd(key, value)) { - throw new ArgumentException(GetResource("ConcurrentDictionary_KeyAlreadyExisted")); + ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_KeyAlreadyExisted); } } @@ -1340,8 +1278,7 @@ namespace System.Collections.Concurrent /// name="keyValuePair"/> is a null reference (Nothing in Visual Basic).</exception> bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> keyValuePair) { - if (keyValuePair.Key == null) throw new ArgumentNullException(GetResource("ConcurrentDictionary_ItemKeyIsNull")); - + if (keyValuePair.Key == null) ThrowHelper.ThrowArgumentNullException(ExceptionResource.ConcurrentDictionary_ItemKeyIsNull); TValue throwAwayValue; return TryRemoveInternal(keyValuePair.Key, out throwAwayValue, true, keyValuePair.Value); } @@ -1387,17 +1324,17 @@ namespace System.Collections.Concurrent /// </exception> void IDictionary.Add(object key, object value) { - if (key == null) throw new ArgumentNullException("key"); - if (!(key is TKey)) throw new ArgumentException(GetResource("ConcurrentDictionary_TypeOfKeyIncorrect")); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); + if (!(key is TKey)) ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_TypeOfKeyIncorrect); - TValue typedValue; + TValue typedValue = default(TValue); try { typedValue = (TValue)value; } catch (InvalidCastException) { - throw new ArgumentException(GetResource("ConcurrentDictionary_TypeOfValueIncorrect")); + ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_TypeOfValueIncorrect); } ((IDictionary<TKey, TValue>)this).Add((TKey)key, typedValue); @@ -1415,7 +1352,7 @@ namespace System.Collections.Concurrent /// (Nothing in Visual Basic).</exception> bool IDictionary.Contains(object key) { - if (key == null) throw new ArgumentNullException("key"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); return (key is TKey) && ((ConcurrentDictionary<TKey, TValue>)this).ContainsKey((TKey)key); } @@ -1475,7 +1412,7 @@ namespace System.Collections.Concurrent /// (Nothing in Visual Basic).</exception> void IDictionary.Remove(object key) { - if (key == null) throw new ArgumentNullException("key"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); TValue throwAwayValue; if (key is TKey) @@ -1517,7 +1454,7 @@ namespace System.Collections.Concurrent { get { - if (key == null) throw new ArgumentNullException("key"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); TValue value; if (key is TKey && this.TryGetValue((TKey)key, out value)) @@ -1529,10 +1466,10 @@ namespace System.Collections.Concurrent } set { - if (key == null) throw new ArgumentNullException("key"); + if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); - if (!(key is TKey)) throw new ArgumentException(GetResource("ConcurrentDictionary_TypeOfKeyIncorrect")); - if (!(value is TValue)) throw new ArgumentException(GetResource("ConcurrentDictionary_TypeOfValueIncorrect")); + if (!(key is TKey)) ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_TypeOfKeyIncorrect); + if (!(value is TValue)) ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_TypeOfValueIncorrect); ((ConcurrentDictionary<TKey, TValue>)this)[(TKey)key] = (TValue)value; } @@ -1563,8 +1500,8 @@ namespace System.Collections.Concurrent [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "ConcurrencyCop just doesn't know about these locks")] void ICollection.CopyTo(Array array, int index) { - if (array == null) throw new ArgumentNullException("array"); - if (index < 0) throw new ArgumentOutOfRangeException("index", GetResource("ConcurrentDictionary_IndexIsNegative")); + if (array == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); + if (index < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ConcurrentDictionary_IndexIsNegative); int locksAcquired = 0; try @@ -1581,7 +1518,7 @@ namespace System.Collections.Concurrent if (array.Length - count < index || count < 0) //"count" itself or "count + index" can overflow { - throw new ArgumentException(GetResource("ConcurrentDictionary_ArrayNotLargeEnough")); + ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_ArrayNotLargeEnough); } // To be consistent with the behavior of ICollection.CopyTo() in Dictionary<TKey,TValue>, @@ -1611,7 +1548,7 @@ namespace System.Collections.Concurrent return; } - throw new ArgumentException(GetResource("ConcurrentDictionary_ArrayIncorrectType"), "array"); + ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_ArrayIncorrectType, ExceptionArgument.array); } finally { @@ -1641,7 +1578,8 @@ namespace System.Collections.Concurrent { get { - throw new NotSupportedException(Environment.GetResourceString("ConcurrentCollection_SyncRoot_NotSupported")); + ThrowHelper.ThrowNotSupportedException(ExceptionResource.ConcurrentCollection_SyncRoot_NotSupported); + return default(object); } } @@ -1850,13 +1788,6 @@ namespace System.Collections.Concurrent /// </summary> private void AcquireAllLocks(ref int locksAcquired) { -#if !FEATURE_CORECLR - if (CDSCollectionETWBCLProvider.Log.IsEnabled()) - { - CDSCollectionETWBCLProvider.Log.ConcurrentDictionary_AcquiringAllLocks(m_tables.m_buckets.Length); - } -#endif //!FEATURE_CORECLR - // First, acquire lock 0 AcquireLocks(0, 1, ref locksAcquired); @@ -1973,19 +1904,7 @@ namespace System.Collections.Concurrent [Conditional("DEBUG")] private void Assert(bool condition) { - Contract.Assert(condition); - } - - /// <summary> - /// A helper function to obtain the string for a particular resource key. - /// </summary> - /// <param name="key"></param> - /// <returns></returns> - private string GetResource(string key) - { - Assert(key != null); - - return Environment.GetResourceString(key); + Debug.Assert(condition); } /// <summary> @@ -2050,46 +1969,5 @@ namespace System.Collections.Concurrent m_enumerator.Reset(); } } - -#if !FEATURE_CORECLR - /// <summary> - /// Get the data array to be serialized - /// </summary> - [OnSerializing] - private void OnSerializing(StreamingContext context) - { - Tables tables = m_tables; - - // save the data into the serialization array to be saved - m_serializationArray = ToArray(); - m_serializationConcurrencyLevel = tables.m_locks.Length; - m_serializationCapacity = tables.m_buckets.Length; - m_comparer = (IEqualityComparer<TKey>)HashHelpers.GetEqualityComparerForSerialization(tables.m_comparer); - } - - /// <summary> - /// Construct the dictionary from a previously serialized one - /// </summary> - [OnDeserialized] - private void OnDeserialized(StreamingContext context) - { - KeyValuePair<TKey, TValue>[] array = m_serializationArray; - - var buckets = new Node[m_serializationCapacity]; - var countPerLock = new int[m_serializationConcurrencyLevel]; - - var locks = new object[m_serializationConcurrencyLevel]; - for (int i = 0; i < locks.Length; i++) - { - locks[i] = new object(); - } - - m_tables = new Tables(buckets, locks, countPerLock, m_comparer); - - InitializeFromCollection(array); - m_serializationArray = null; - - } -#endif } } diff --git a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs index 9164eadad1..7aa5971690 100644 --- a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs +++ b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs @@ -38,7 +38,6 @@ namespace System.Collections.Concurrent [ComVisible(false)] [DebuggerDisplay("Count = {Count}")] [DebuggerTypeProxy(typeof(SystemCollectionsConcurrent_ProducerConsumerCollectionDebugView<>))] - [HostProtection(Synchronization = true, ExternalThreading = true)] [Serializable] public class ConcurrentQueue<T> : IProducerConsumerCollection<T>, IReadOnlyCollection<T> { @@ -77,7 +76,7 @@ namespace System.Collections.Concurrent int index = 0; foreach (T element in collection) { - Contract.Assert(index >= 0 && index < SEGMENT_SIZE); + Debug.Assert(index >= 0 && index < SEGMENT_SIZE); localTail.UnsafeAdd(element); index++; @@ -103,7 +102,7 @@ namespace System.Collections.Concurrent { if (collection == null) { - throw new ArgumentNullException("collection"); + throw new ArgumentNullException(nameof(collection)); } InitializeFromCollection(collection); @@ -125,7 +124,7 @@ namespace System.Collections.Concurrent [OnDeserialized] private void OnDeserialized(StreamingContext context) { - Contract.Assert(m_serializationArray != null); + Debug.Assert(m_serializationArray != null); InitializeFromCollection(m_serializationArray); m_serializationArray = null; } @@ -160,7 +159,7 @@ namespace System.Collections.Concurrent // Validate arguments. if (array == null) { - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); } // We must be careful not to corrupt the array, so we will first accumulate an @@ -441,7 +440,7 @@ namespace System.Collections.Concurrent { if (array == null) { - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); } // We must be careful not to corrupt the array, so we will first accumulate an @@ -689,7 +688,7 @@ namespace System.Collections.Concurrent m_array = new T[SEGMENT_SIZE]; m_state = new VolatileBool[SEGMENT_SIZE]; //all initialized to false m_high = -1; - Contract.Assert(index >= 0); + Debug.Assert(index >= 0); m_index = index; m_source = source; } @@ -721,7 +720,7 @@ namespace System.Collections.Concurrent /// <param name="value"></param> internal void UnsafeAdd(T value) { - Contract.Assert(m_high < SEGMENT_SIZE - 1); + Debug.Assert(m_high < SEGMENT_SIZE - 1); m_high++; m_array[m_high] = value; m_state[m_high].m_value = true; @@ -737,7 +736,7 @@ namespace System.Collections.Concurrent /// <returns>the reference to the new Segment</returns> internal Segment UnsafeGrow() { - Contract.Assert(m_high >= SEGMENT_SIZE - 1); + Debug.Assert(m_high >= SEGMENT_SIZE - 1); Segment newSegment = new Segment(m_index + 1, m_source); //m_index is Int64, we don't need to worry about overflow m_next = newSegment; return newSegment; @@ -753,7 +752,7 @@ namespace System.Collections.Concurrent //no CAS is needed, since there is no contention (other threads are blocked, busy waiting) Segment newSegment = new Segment(m_index + 1, m_source); //m_index is Int64, we don't need to worry about overflow m_next = newSegment; - Contract.Assert(m_source.m_tail == this); + Debug.Assert(m_source.m_tail == this); m_source.m_tail = m_next; } @@ -860,7 +859,7 @@ namespace System.Collections.Concurrent { spinLocal.SpinOnce(); } - Contract.Assert(m_source.m_head == this); + Debug.Assert(m_source.m_head == this); m_source.m_head = m_next; } return true; diff --git a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs index 15d4176cff..c36d96c26c 100644 --- a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs +++ b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs @@ -45,10 +45,6 @@ namespace System.Collections.Concurrent /// </remarks> [DebuggerDisplay("Count = {Count}")] [DebuggerTypeProxy(typeof(SystemCollectionsConcurrent_ProducerConsumerCollectionDebugView<>))] - [HostProtection(Synchronization = true, ExternalThreading = true)] -#if !FEATURE_CORECLR - [Serializable] -#endif //!FEATURE_CORECLR public class ConcurrentStack<T> : IProducerConsumerCollection<T>, IReadOnlyCollection<T> { /// <summary> @@ -70,15 +66,8 @@ namespace System.Collections.Concurrent } } -#if !FEATURE_CORECLR - [NonSerialized] -#endif //!FEATURE_CORECLR private volatile Node m_head; // The stack is a singly linked list, and only remembers the head. -#if !FEATURE_CORECLR - private T[] m_serializationArray; // Used for custom serialization. -#endif //!FEATURE_CORECLR - private const int BACKOFF_MAX_YIELDS = 8; // Arbitrary number to cap backoff. /// <summary> @@ -101,7 +90,7 @@ namespace System.Collections.Concurrent { if (collection == null) { - throw new ArgumentNullException("collection"); + throw new ArgumentNullException(nameof(collection)); } InitializeFromCollection(collection); } @@ -124,50 +113,6 @@ namespace System.Collections.Concurrent m_head = lastNode; } -#if !FEATURE_CORECLR - /// <summary> - /// Get the data array to be serialized - /// </summary> - [OnSerializing] - private void OnSerializing(StreamingContext context) - { - // save the data into the serialization array to be saved - m_serializationArray = ToArray(); - } - - /// <summary> - /// Construct the stack from a previously seiralized one - /// </summary> - [OnDeserialized] - private void OnDeserialized(StreamingContext context) - { - Contract.Assert(m_serializationArray != null); - // Add the elements to our stack. We need to add them from head-to-tail, to - // preserve the original ordering of the stack before serialization. - Node prevNode = null; - Node head = null; - for (int i = 0; i < m_serializationArray.Length; i++) - { - Node currNode = new Node(m_serializationArray[i]); - - if (prevNode == null) - { - head = currNode; - } - else - { - prevNode.m_next = currNode; - } - - prevNode = currNode; - } - - m_head = head; - m_serializationArray = null; - } -#endif //!FEATURE_CORECLR - - /// <summary> /// Gets a value that indicates whether the <see cref="ConcurrentStack{T}"/> is empty. /// </summary> @@ -221,7 +166,6 @@ namespace System.Collections.Concurrent } } - /// <summary> /// Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection"/> is /// synchronized with the SyncRoot. @@ -293,7 +237,7 @@ namespace System.Collections.Concurrent // Validate arguments. if (array == null) { - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); } // We must be careful not to corrupt the array, so we will first accumulate an @@ -327,7 +271,7 @@ namespace System.Collections.Concurrent { if (array == null) { - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); } // We must be careful not to corrupt the array, so we will first accumulate an @@ -379,7 +323,7 @@ namespace System.Collections.Concurrent { if (items == null) { - throw new ArgumentNullException("items"); + throw new ArgumentNullException(nameof(items)); } PushRange(items, 0, items.Length); } @@ -455,13 +399,6 @@ namespace System.Collections.Concurrent } while (Interlocked.CompareExchange( ref m_head, head, tail.m_next) != tail.m_next); - -#if !FEATURE_CORECLR - if (CDSCollectionETWBCLProvider.Log.IsEnabled()) - { - CDSCollectionETWBCLProvider.Log.ConcurrentStack_FastPushFailed(spin.Count); - } -#endif // !FEATURE_CORECLR } /// <summary> @@ -471,16 +408,16 @@ namespace System.Collections.Concurrent { if (items == null) { - throw new ArgumentNullException("items"); + throw new ArgumentNullException(nameof(items)); } if (count < 0) { - throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ConcurrentStack_PushPopRange_CountOutOfRange")); + throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ConcurrentStack_PushPopRange_CountOutOfRange")); } int length = items.Length; if (startIndex >= length || startIndex < 0) { - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ConcurrentStack_PushPopRange_StartOutOfRange")); + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ConcurrentStack_PushPopRange_StartOutOfRange")); } if (length - count < startIndex) //instead of (startIndex + count > items.Length) to prevent overflow { @@ -584,7 +521,7 @@ namespace System.Collections.Concurrent { if (items == null) { - throw new ArgumentNullException("items"); + throw new ArgumentNullException(nameof(items)); } return TryPopRange(items, 0, items.Length); @@ -683,12 +620,6 @@ namespace System.Collections.Concurrent // Is the stack empty? if (head == null) { -#if !FEATURE_CORECLR - if (count == 1 && CDSCollectionETWBCLProvider.Log.IsEnabled()) - { - CDSCollectionETWBCLProvider.Log.ConcurrentStack_FastPopFailed(spin.Count); - } -#endif //!FEATURE_CORECLR poppedHead = null; return 0; } @@ -702,12 +633,6 @@ namespace System.Collections.Concurrent // Try to swap the new head. If we succeed, break out of the loop. if (Interlocked.CompareExchange(ref m_head, next.m_next, head) == head) { -#if !FEATURE_CORECLR - if (count == 1 && CDSCollectionETWBCLProvider.Log.IsEnabled()) - { - CDSCollectionETWBCLProvider.Log.ConcurrentStack_FastPopFailed(spin.Count); - } -#endif //!FEATURE_CORECLR // Return the popped Node. poppedHead = head; return nodesCount; diff --git a/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs b/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs index a74f69069a..56be7759c9 100644 --- a/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs +++ b/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs @@ -97,7 +97,7 @@ namespace System.Collections.Concurrent { if (collection == null) { - throw new ArgumentNullException("collection"); + throw new ArgumentNullException(nameof(collection)); } m_collection = collection; diff --git a/src/mscorlib/src/System/Collections/Concurrent/OrderablePartitioner.cs b/src/mscorlib/src/System/Collections/Concurrent/OrderablePartitioner.cs index 02263b7f97..33e3c88e9a 100644 --- a/src/mscorlib/src/System/Collections/Concurrent/OrderablePartitioner.cs +++ b/src/mscorlib/src/System/Collections/Concurrent/OrderablePartitioner.cs @@ -61,7 +61,6 @@ namespace System.Collections.Concurrent /// </ol> /// </para> /// </remarks> - [HostProtection(Synchronization = true, ExternalThreading = true)] public abstract class OrderablePartitioner<TSource> : Partitioner<TSource> { /// <summary> diff --git a/src/mscorlib/src/System/Collections/Concurrent/Partitioner.cs b/src/mscorlib/src/System/Collections/Concurrent/Partitioner.cs index 3d54c1471b..0192b1942c 100644 --- a/src/mscorlib/src/System/Collections/Concurrent/Partitioner.cs +++ b/src/mscorlib/src/System/Collections/Concurrent/Partitioner.cs @@ -44,7 +44,6 @@ namespace System.Collections.Concurrent /// </ol> /// </para> /// </remarks> - [HostProtection(Synchronization = true, ExternalThreading = true)] public abstract class Partitioner<TSource> { /// <summary> diff --git a/src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs b/src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs index 2169c6dee7..9b36c053ad 100644 --- a/src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs +++ b/src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs @@ -14,6 +14,7 @@ using System.Collections.Generic; using System.Security.Permissions; using System.Threading; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Runtime.InteropServices; @@ -26,9 +27,6 @@ namespace System.Collections.Concurrent /// non-blocking. These behaviors can be overridden via this enumeration. /// </summary> [Flags] -#if !FEATURE_CORECLR - [Serializable] -#endif public enum EnumerablePartitionerOptions { /// <summary> @@ -71,7 +69,6 @@ namespace System.Collections.Concurrent /// thread. /// </para> /// </remarks> - [HostProtection(Synchronization = true, ExternalThreading = true)] public static class Partitioner { /// <summary> @@ -91,7 +88,7 @@ namespace System.Collections.Concurrent { if (list == null) { - throw new ArgumentNullException("list"); + throw new ArgumentNullException(nameof(list)); } if (loadBalance) { @@ -122,7 +119,7 @@ namespace System.Collections.Concurrent if (array == null) { - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); } if (loadBalance) { @@ -172,11 +169,11 @@ namespace System.Collections.Concurrent { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if ((partitionerOptions & (~EnumerablePartitionerOptions.NoBuffering)) != 0) - throw new ArgumentOutOfRangeException("partitionerOptions"); + throw new ArgumentOutOfRangeException(nameof(partitionerOptions)); return (new DynamicPartitionerForIEnumerable<TSource>(source, partitionerOptions)); } @@ -194,7 +191,7 @@ namespace System.Collections.Concurrent // load balancing on a busy system if you make it higher than 1. int coreOversubscriptionRate = 3; - if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive"); + if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException(nameof(toExclusive)); long rangeSize = (toExclusive - fromInclusive) / (PlatformHelper.ProcessorCount * coreOversubscriptionRate); if (rangeSize == 0) rangeSize = 1; @@ -212,8 +209,8 @@ namespace System.Collections.Concurrent /// less than or equal to 0.</exception> public static OrderablePartitioner<Tuple<long, long>> Create(long fromInclusive, long toExclusive, long rangeSize) { - if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive"); - if (rangeSize <= 0) throw new ArgumentOutOfRangeException("rangeSize"); + if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException(nameof(toExclusive)); + if (rangeSize <= 0) throw new ArgumentOutOfRangeException(nameof(rangeSize)); return Partitioner.Create(CreateRanges(fromInclusive, toExclusive, rangeSize), EnumerablePartitionerOptions.NoBuffering); // chunk one range at a time } @@ -251,7 +248,7 @@ namespace System.Collections.Concurrent // load balancing on a busy system if you make it higher than 1. int coreOversubscriptionRate = 3; - if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive"); + if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException(nameof(toExclusive)); int rangeSize = (toExclusive - fromInclusive) / (PlatformHelper.ProcessorCount * coreOversubscriptionRate); if (rangeSize == 0) rangeSize = 1; @@ -269,8 +266,8 @@ namespace System.Collections.Concurrent /// less than or equal to 0.</exception> public static OrderablePartitioner<Tuple<int, int>> Create(int fromInclusive, int toExclusive, int rangeSize) { - if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive"); - if (rangeSize <= 0) throw new ArgumentOutOfRangeException("rangeSize"); + if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException(nameof(toExclusive)); + if (rangeSize <= 0) throw new ArgumentOutOfRangeException(nameof(rangeSize)); return Partitioner.Create(CreateRanges(fromInclusive, toExclusive, rangeSize), EnumerablePartitionerOptions.NoBuffering); // chunk one range at a time } @@ -431,7 +428,7 @@ namespace System.Collections.Concurrent //perform deferred allocating of the local variables. if (m_localOffset == null) { - Contract.Assert(m_currentChunkSize == null); + Debug.Assert(m_currentChunkSize == null); m_localOffset = new SharedInt(-1); m_currentChunkSize = new SharedInt(0); m_doublingCountdown = CHUNK_DOUBLING_RATE; @@ -449,7 +446,7 @@ namespace System.Collections.Concurrent { // The second part of the || condition is necessary to handle the case when MoveNext() is called // after a previous MoveNext call returned false. - Contract.Assert(m_localOffset.Value == m_currentChunkSize.Value - 1 || m_currentChunkSize.Value == 0); + Debug.Assert(m_localOffset.Value == m_currentChunkSize.Value - 1 || m_currentChunkSize.Value == 0); //set the requested chunk size to a proper value int requestedChunkSize; @@ -470,11 +467,11 @@ namespace System.Collections.Concurrent // Decrement your doubling countdown m_doublingCountdown--; - Contract.Assert(requestedChunkSize > 0 && requestedChunkSize <= m_maxChunkSize); + Debug.Assert(requestedChunkSize > 0 && requestedChunkSize <= m_maxChunkSize); //GrabNextChunk will update the value of m_currentChunkSize if (GrabNextChunk(requestedChunkSize)) { - Contract.Assert(m_currentChunkSize.Value <= requestedChunkSize && m_currentChunkSize.Value > 0); + Debug.Assert(m_currentChunkSize.Value <= requestedChunkSize && m_currentChunkSize.Value > 0); m_localOffset.Value = 0; return true; } @@ -517,7 +514,7 @@ namespace System.Collections.Concurrent { if (partitionCount <= 0) { - throw new ArgumentOutOfRangeException("partitionCount"); + throw new ArgumentOutOfRangeException(nameof(partitionCount)); } IEnumerator<KeyValuePair<long, TSource>>[] partitions = new IEnumerator<KeyValuePair<long, TSource>>[partitionCount]; @@ -715,10 +712,10 @@ namespace System.Collections.Concurrent /// </returns> internal bool GrabChunk_Single(KeyValuePair<long,TSource>[] destArray, int requestedChunkSize, ref int actualNumElementsGrabbed) { - Contract.Assert(m_useSingleChunking, "Expected m_useSingleChecking to be true"); - Contract.Assert(requestedChunkSize == 1, "Got requested chunk size of " + requestedChunkSize + " when single-chunking was on"); - Contract.Assert(actualNumElementsGrabbed == 0, "Expected actualNumElementsGrabbed == 0, instead it is " + actualNumElementsGrabbed); - Contract.Assert(destArray.Length == 1, "Expected destArray to be of length 1, instead its length is " + destArray.Length); + Debug.Assert(m_useSingleChunking, "Expected m_useSingleChecking to be true"); + Debug.Assert(requestedChunkSize == 1, "Got requested chunk size of " + requestedChunkSize + " when single-chunking was on"); + Debug.Assert(actualNumElementsGrabbed == 0, "Expected actualNumElementsGrabbed == 0, instead it is " + actualNumElementsGrabbed); + Debug.Assert(destArray.Length == 1, "Expected destArray to be of length 1, instead its length is " + destArray.Length); lock (m_sharedLock) { @@ -764,8 +761,8 @@ namespace System.Collections.Concurrent /// </returns> internal bool GrabChunk_Buffered(KeyValuePair<long,TSource>[] destArray, int requestedChunkSize, ref int actualNumElementsGrabbed) { - Contract.Assert(requestedChunkSize > 0); - Contract.Assert(!m_useSingleChunking, "Did not expect to be in single-chunking mode"); + Debug.Assert(requestedChunkSize > 0); + Debug.Assert(!m_useSingleChunking, "Did not expect to be in single-chunking mode"); TryCopyFromFillBuffer(destArray, requestedChunkSize, ref actualNumElementsGrabbed); @@ -803,7 +800,7 @@ namespace System.Collections.Concurrent while( m_activeCopiers > 0) sw.SpinOnce(); } - Contract.Assert(m_sharedIndex != null); //already been allocated in MoveNext() before calling GrabNextChunk + Debug.Assert(m_sharedIndex != null); //already been allocated in MoveNext() before calling GrabNextChunk // Now's the time to actually enumerate the source @@ -940,7 +937,7 @@ namespace System.Collections.Concurrent /// </returns> override protected bool GrabNextChunk(int requestedChunkSize) { - Contract.Assert(requestedChunkSize > 0); + Debug.Assert(requestedChunkSize > 0); if (HasNoElementsLeft) { @@ -973,8 +970,8 @@ namespace System.Collections.Concurrent { //we only set it from false to true once //we should never set it back in any circumstances - Contract.Assert(value); - Contract.Assert(!m_hasNoElementsLeft.Value); + Debug.Assert(value); + Debug.Assert(!m_hasNoElementsLeft.Value); m_hasNoElementsLeft.Value = true; } } @@ -988,8 +985,8 @@ namespace System.Collections.Concurrent { throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext")); } - Contract.Assert(m_localList != null); - Contract.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value); + Debug.Assert(m_localList != null); + Debug.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value); return (m_localList[m_localOffset.Value]); } } @@ -1053,7 +1050,7 @@ namespace System.Collections.Concurrent { if (partitionCount <= 0) { - throw new ArgumentOutOfRangeException("partitionCount"); + throw new ArgumentOutOfRangeException(nameof(partitionCount)); } IEnumerator<KeyValuePair<long, TSource>>[] partitions = new IEnumerator<KeyValuePair<long, TSource>>[partitionCount]; @@ -1127,11 +1124,11 @@ namespace System.Collections.Concurrent /// </returns> override protected bool GrabNextChunk(int requestedChunkSize) { - Contract.Assert(requestedChunkSize > 0); + Debug.Assert(requestedChunkSize > 0); while (!HasNoElementsLeft) { - Contract.Assert(m_sharedIndex != null); + Debug.Assert(m_sharedIndex != null); // use the new Volatile.Read method because it is cheaper than Interlocked.Read on AMD64 architecture long oldSharedIndex = Volatile.Read(ref m_sharedIndex.Value); @@ -1173,13 +1170,13 @@ namespace System.Collections.Concurrent { get { - Contract.Assert(m_sharedIndex != null); + Debug.Assert(m_sharedIndex != null); // use the new Volatile.Read method because it is cheaper than Interlocked.Read on AMD64 architecture return Volatile.Read(ref m_sharedIndex.Value) >= SourceCount - 1; } set { - Contract.Assert(false); + Debug.Assert(false); } } @@ -1268,7 +1265,7 @@ namespace System.Collections.Concurrent throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext")); } - Contract.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value); + Debug.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value); return new KeyValuePair<long, TSource>(m_startIndex + m_localOffset.Value, m_sharedReader[m_startIndex + m_localOffset.Value]); } @@ -1352,7 +1349,7 @@ namespace System.Collections.Concurrent throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext")); } - Contract.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value); + Debug.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value); return new KeyValuePair<long, TSource>(m_startIndex + m_localOffset.Value, m_sharedReader[m_startIndex + m_localOffset.Value]); } @@ -1417,7 +1414,7 @@ namespace System.Collections.Concurrent { if (partitionCount <= 0) { - throw new ArgumentOutOfRangeException("partitionCount"); + throw new ArgumentOutOfRangeException(nameof(partitionCount)); } int quotient, remainder; @@ -1539,7 +1536,7 @@ namespace System.Collections.Concurrent internal StaticIndexRangePartitionerForIList(IList<TSource> list) : base() { - Contract.Assert(list != null); + Debug.Assert(list != null); m_list = list; } override protected int SourceCount @@ -1565,7 +1562,7 @@ namespace System.Collections.Concurrent internal StaticIndexRangePartitionForIList(IList<TSource> list, int startIndex, int endIndex) : base(startIndex, endIndex) { - Contract.Assert(startIndex >= 0 && endIndex <= list.Count - 1); + Debug.Assert(startIndex >= 0 && endIndex <= list.Count - 1); m_list = list; } @@ -1579,7 +1576,7 @@ namespace System.Collections.Concurrent throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext")); } - Contract.Assert(m_offset >= m_startIndex && m_offset <= m_endIndex); + Debug.Assert(m_offset >= m_startIndex && m_offset <= m_endIndex); return (new KeyValuePair<long, TSource>(m_offset, m_list[m_offset])); } } @@ -1597,7 +1594,7 @@ namespace System.Collections.Concurrent internal StaticIndexRangePartitionerForArray(TSource[] array) : base() { - Contract.Assert(array != null); + Debug.Assert(array != null); m_array = array; } override protected int SourceCount @@ -1622,7 +1619,7 @@ namespace System.Collections.Concurrent internal StaticIndexRangePartitionForArray(TSource[] array, int startIndex, int endIndex) : base(startIndex, endIndex) { - Contract.Assert(startIndex >= 0 && endIndex <= array.Length - 1); + Debug.Assert(startIndex >= 0 && endIndex <= array.Length - 1); m_array = array; } @@ -1636,7 +1633,7 @@ namespace System.Collections.Concurrent throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext")); } - Contract.Assert(m_offset >= m_startIndex && m_offset <= m_endIndex); + Debug.Assert(m_offset >= m_startIndex && m_offset <= m_endIndex); return (new KeyValuePair<long, TSource>(m_offset, m_array[m_offset])); } } @@ -1704,30 +1701,15 @@ namespace System.Collections.Concurrent if (typeof(TSource).IsValueType) { -#if !FEATURE_CORECLR // Marshal.SizeOf is not supported in CoreCLR - - if (typeof(TSource).StructLayoutAttribute.Value == LayoutKind.Explicit) - { - chunkSize = Math.Max(1, DEFAULT_BYTES_PER_CHUNK / Marshal.SizeOf(typeof(TSource))); - } - else - { - // We choose '128' because this ensures, no matter the actual size of the value type, - // the total bytes used will be a multiple of 128. This ensures it's cache aligned. - chunkSize = 128; - } -#else chunkSize = 128; -#endif } else { - Contract.Assert((DEFAULT_BYTES_PER_CHUNK % IntPtr.Size) == 0, "bytes per chunk should be a multiple of pointer size"); + Debug.Assert((DEFAULT_BYTES_PER_CHUNK % IntPtr.Size) == 0, "bytes per chunk should be a multiple of pointer size"); chunkSize = (DEFAULT_BYTES_PER_CHUNK / IntPtr.Size); } return chunkSize; } #endregion - } } diff --git a/src/mscorlib/src/System/Collections/DictionaryEntry.cs b/src/mscorlib/src/System/Collections/DictionaryEntry.cs index fc1d57fe55..3ee392bb0d 100644 --- a/src/mscorlib/src/System/Collections/DictionaryEntry.cs +++ b/src/mscorlib/src/System/Collections/DictionaryEntry.cs @@ -51,5 +51,12 @@ namespace System.Collections { _value = value; } } + + // BLOCKED (do not add now): [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 6e28493ef8..a610fce016 100644 --- a/src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs +++ b/src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs @@ -36,16 +36,16 @@ namespace System.Collections { public void CopyTo(Array array, int index) { if (array==null) - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); if (array.Rank != 1) throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported")); if (index < 0) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if ( array.Length - index < this.Count ) - throw new ArgumentException( Environment.GetResourceString("ArgumentOutOfRange_Index"), "index"); + throw new ArgumentException( Environment.GetResourceString("ArgumentOutOfRange_Index"), nameof(index)); Contract.EndContractBlock(); // the actual copy is a NOP @@ -74,21 +74,21 @@ namespace System.Collections { public Object this[Object key] { get { if (key == null) { - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); } Contract.EndContractBlock(); return null; } set { if (key == null) { - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); } if (!key.GetType().IsSerializable) - throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "key"); + throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(key)); if( (value != null) && (!value.GetType().IsSerializable ) ) - throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "value"); + throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(value)); Contract.EndContractBlock(); throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly")); @@ -113,14 +113,14 @@ namespace System.Collections { public void Add(Object key, Object value) { if (key == null) { - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); } if (!key.GetType().IsSerializable) - throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "key" ); + throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(key) ); if( (value != null) && (!value.GetType().IsSerializable) ) - throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "value"); + throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(value)); Contract.EndContractBlock(); throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly")); diff --git a/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs b/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs index b2fed9d78f..298ac3e177 100644 --- a/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs +++ b/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs @@ -17,6 +17,7 @@ namespace System.Collections.Generic using System; using System.Globalization; using System.Runtime.CompilerServices; + using System.Diagnostics; using System.Diagnostics.Contracts; using System.Runtime.Versioning; @@ -49,16 +50,7 @@ namespace System.Collections.Generic } internal static void ThrowOrIgnoreBadComparer(Object comparer) { - // This is hit when an invarant of QuickSort is violated due to a bad IComparer implementation (for - // example, imagine an IComparer that returns 0 when items are equal but -1 all other times). - // - // We could have thrown this exception on v4, but due to changes in v4.5 around how we partition arrays - // there are different sets of input where we would throw this exception. In order to reduce overall risk from - // an app compat persective, we're changing to never throw on v4. Instead, we'll return with a partially - // sorted array. - if(BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) { - throw new ArgumentException(Environment.GetResourceString("Arg_BogusIComparer", comparer)); - } + throw new ArgumentException(Environment.GetResourceString("Arg_BogusIComparer", comparer)); } } @@ -81,7 +73,6 @@ namespace System.Collections.Generic } } - [System.Security.SecuritySafeCritical] // auto-generated private static IArraySortHelper<T> CreateArraySortHelper() { if (typeof(IComparable<T>).IsAssignableFrom(typeof(T))) @@ -99,8 +90,8 @@ namespace System.Collections.Generic public void Sort(T[] keys, int index, int length, IComparer<T> comparer) { - Contract.Assert(keys != null, "Check the arguments in the caller!"); - Contract.Assert( index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!"); + 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!"); // Add a try block here to detect IComparers (or their // underlying IComparables, etc) that are bogus. @@ -111,22 +102,7 @@ namespace System.Collections.Generic comparer = Comparer<T>.Default; } -#if FEATURE_CORECLR - // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade - // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka - // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort. - - IntrospectiveSort(keys, index, length, comparer); -#else - if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) - { - IntrospectiveSort(keys, index, length, comparer); - } - else - { - DepthLimitedQuickSort(keys, index, length + index - 1, comparer, IntrospectiveSortUtilities.QuickSortDepthThreshold); - } -#endif + IntrospectiveSort(keys, index, length, comparer.Compare); } catch (IndexOutOfRangeException) { @@ -157,6 +133,27 @@ namespace System.Collections.Generic #endregion + internal static void Sort(T[] keys, int index, int length, Comparison<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(comparer != null, "Check the arguments in the caller!"); + + // Add a try block here to detect bogus comparisons + try + { + IntrospectiveSort(keys, index, length, comparer); + } + catch (IndexOutOfRangeException) + { + IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer(comparer); + } + catch (Exception e) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e); + } + } + internal static int InternalBinarySearch(T[] array, int index, int length, T value, IComparer<T> comparer) { Contract.Requires(array != null, "Check the arguments in the caller!"); @@ -183,11 +180,11 @@ namespace System.Collections.Generic return ~lo; } - private static void SwapIfGreater(T[] keys, IComparer<T> comparer, int a, int b) + private static void SwapIfGreater(T[] keys, Comparison<T> comparer, int a, int b) { if (a != b) { - if (comparer.Compare(keys[a], keys[b]) > 0) + if (comparer(keys[a], keys[b]) > 0) { T key = keys[a]; keys[a] = keys[b]; @@ -198,7 +195,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]; @@ -206,63 +203,7 @@ namespace System.Collections.Generic } } - internal static void DepthLimitedQuickSort(T[] keys, int left, int right, IComparer<T> comparer, int depthLimit) - { - do - { - if (depthLimit == 0) - { - Heapsort(keys, left, right, comparer); - return; - } - - int i = left; - int j = right; - - // pre-sort the low, middle (pivot), and high values in place. - // this improves performance in the face of already sorted data, or - // data that is made up of multiple sorted runs appended together. - int middle = i + ((j - i) >> 1); - SwapIfGreater(keys, comparer, i, middle); // swap the low with the mid point - SwapIfGreater(keys, comparer, i, j); // swap the low with the high - SwapIfGreater(keys, comparer, middle, j); // swap the middle with the high - - T x = keys[middle]; - do - { - while (comparer.Compare(keys[i], x) < 0) i++; - while (comparer.Compare(x, keys[j]) < 0) j--; - Contract.Assert(i >= left && j <= right, "(i>=left && j<=right) Sort failed - Is your IComparer bogus?"); - if (i > j) break; - if (i < j) - { - T key = keys[i]; - keys[i] = keys[j]; - keys[j] = key; - } - i++; - j--; - } while (i <= j); - - // The next iteration of the while loop is to "recursively" sort the larger half of the array and the - // following calls recursively sort the smaller half. So we subtract one from depthLimit here so - // both sorts see the new value. - depthLimit--; - - if (j - left <= right - i) - { - if (left < j) DepthLimitedQuickSort(keys, left, j, comparer, depthLimit); - left = i; - } - else - { - if (i < right) DepthLimitedQuickSort(keys, i, right, comparer, depthLimit); - right = j; - } - } while (left < right); - } - - internal static void IntrospectiveSort(T[] keys, int left, int length, IComparer<T> comparer) + internal static void IntrospectiveSort(T[] keys, int left, int length, Comparison<T> comparer) { Contract.Requires(keys != null); Contract.Requires(comparer != null); @@ -277,7 +218,7 @@ namespace System.Collections.Generic IntroSort(keys, left, length + left - 1, 2 * IntrospectiveSortUtilities.FloorLog2(keys.Length), comparer); } - private static void IntroSort(T[] keys, int lo, int hi, int depthLimit, IComparer<T> comparer) + private static void IntroSort(T[] keys, int lo, int hi, int depthLimit, Comparison<T> comparer) { Contract.Requires(keys != null); Contract.Requires(comparer != null); @@ -324,7 +265,7 @@ namespace System.Collections.Generic } } - private static int PickPivotAndPartition(T[] keys, int lo, int hi, IComparer<T> comparer) + private static int PickPivotAndPartition(T[] keys, int lo, int hi, Comparison<T> comparer) { Contract.Requires(keys != null); Contract.Requires(comparer != null); @@ -347,8 +288,8 @@ namespace System.Collections.Generic while (left < right) { - while (comparer.Compare(keys[++left], pivot) < 0) ; - while (comparer.Compare(pivot, keys[--right]) < 0) ; + while (comparer(keys[++left], pivot) < 0) ; + while (comparer(pivot, keys[--right]) < 0) ; if (left >= right) break; @@ -361,7 +302,7 @@ namespace System.Collections.Generic return left; } - private static void Heapsort(T[] keys, int lo, int hi, IComparer<T> comparer) + private static void Heapsort(T[] keys, int lo, int hi, Comparison<T> comparer) { Contract.Requires(keys != null); Contract.Requires(comparer != null); @@ -381,7 +322,7 @@ namespace System.Collections.Generic } } - private static void DownHeap(T[] keys, int i, int n, int lo, IComparer<T> comparer) + private static void DownHeap(T[] keys, int i, int n, int lo, Comparison<T> comparer) { Contract.Requires(keys != null); Contract.Requires(comparer != null); @@ -393,11 +334,11 @@ namespace System.Collections.Generic while (i <= n / 2) { child = 2 * i; - if (child < n && comparer.Compare(keys[lo + child - 1], keys[lo + child]) < 0) + if (child < n && comparer(keys[lo + child - 1], keys[lo + child]) < 0) { child++; } - if (!(comparer.Compare(d, keys[lo + child - 1]) < 0)) + if (!(comparer(d, keys[lo + child - 1]) < 0)) break; keys[lo + i - 1] = keys[lo + child - 1]; i = child; @@ -405,7 +346,7 @@ namespace System.Collections.Generic keys[lo + i - 1] = d; } - private static void InsertionSort(T[] keys, int lo, int hi, IComparer<T> comparer) + private static void InsertionSort(T[] keys, int lo, int hi, Comparison<T> comparer) { Contract.Requires(keys != null); Contract.Requires(lo >= 0); @@ -418,7 +359,7 @@ namespace System.Collections.Generic { j = i; t = keys[i + 1]; - while (j >= lo && comparer.Compare(t, keys[j]) < 0) + while (j >= lo && comparer(t, keys[j]) < 0) { keys[j + 1] = keys[j]; j--; @@ -439,49 +380,18 @@ namespace System.Collections.Generic public void Sort(T[] keys, int index, int length, IComparer<T> comparer) { - Contract.Assert(keys != null, "Check the arguments in the caller!"); - Contract.Assert(index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!"); + 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!"); try { - if (comparer == null || comparer == Comparer<T>.Default) { - -#if FEATURE_CORECLR - // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade - // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka - // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort. - + if (comparer == null || comparer == Comparer<T>.Default) + { IntrospectiveSort(keys, index, length); -#else - // call the faster version of our sort algorithm if the user doesn't provide a comparer - if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) - { - IntrospectiveSort(keys, index, length); - } - else - { - DepthLimitedQuickSort(keys, index, length + index - 1, IntrospectiveSortUtilities.QuickSortDepthThreshold); - } -#endif } else { -#if FEATURE_CORECLR - // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade - // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka - // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort. - - ArraySortHelper<T>.IntrospectiveSort(keys, index, length, comparer); -#else - if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) - { - ArraySortHelper<T>.IntrospectiveSort(keys, index, length, comparer); - } - else - { - ArraySortHelper<T>.DepthLimitedQuickSort(keys, index, length + index - 1, comparer, IntrospectiveSortUtilities.QuickSortDepthThreshold); - } -#endif + ArraySortHelper<T>.IntrospectiveSort(keys, index, length, comparer.Compare); } } catch (IndexOutOfRangeException) @@ -496,8 +406,8 @@ namespace System.Collections.Generic public int BinarySearch(T[] array, int index, int length, T value, IComparer<T> comparer) { - Contract.Assert(array != null, "Check the arguments in the caller!"); - Contract.Assert(index >= 0 && length >= 0 && (array.Length - index >= length), "Check the arguments in the caller!"); + Debug.Assert(array != null, "Check the arguments in the caller!"); + Debug.Assert(index >= 0 && length >= 0 && (array.Length - index >= length), "Check the arguments in the caller!"); try { @@ -583,78 +493,6 @@ namespace System.Collections.Generic } } - private static void DepthLimitedQuickSort(T[] keys, int left, int right, int depthLimit) - { - Contract.Requires(keys != null); - Contract.Requires(0 <= left && left < keys.Length); - Contract.Requires(0 <= right && right < keys.Length); - - // The code in this function looks very similar to QuickSort in ArraySortHelper<T> class. - // The difference is that T is constrainted to IComparable<T> here. - // So the IL code will be different. This function is faster than the one in ArraySortHelper<T>. - - do - { - if (depthLimit == 0) - { - Heapsort(keys, left, right); - return; - } - - int i = left; - int j = right; - - // pre-sort the low, middle (pivot), and high values in place. - // this improves performance in the face of already sorted data, or - // data that is made up of multiple sorted runs appended together. - int middle = i + ((j - i) >> 1); - SwapIfGreaterWithItems(keys, i, middle); // swap the low with the mid point - SwapIfGreaterWithItems(keys, i, j); // swap the low with the high - SwapIfGreaterWithItems(keys, middle, j); // swap the middle with the high - - T x = keys[middle]; - do - { - if (x == null) - { - // if x null, the loop to find two elements to be switched can be reduced. - while (keys[j] != null) j--; - } - else - { - while (x.CompareTo(keys[i]) > 0) i++; - while (x.CompareTo(keys[j]) < 0) j--; - } - Contract.Assert(i >= left && j <= right, "(i>=left && j<=right) Sort failed - Is your IComparer bogus?"); - if (i > j) break; - if (i < j) - { - T key = keys[i]; - keys[i] = keys[j]; - keys[j] = key; - } - i++; - j--; - } while (i <= j); - - // The next iteration of the while loop is to "recursively" sort the larger half of the array and the - // following calls recursively sort the smaller half. So we subtract one from depthLimit here so - // both sorts see the new value. - depthLimit--; - - if (j - left <= right - i) - { - if (left < j) DepthLimitedQuickSort(keys, left, j, depthLimit); - left = i; - } - else - { - if (i < right) DepthLimitedQuickSort(keys, i, right, depthLimit); - right = j; - } - } while (left < right); - } - internal static void IntrospectiveSort(T[] keys, int left, int length) { Contract.Requires(keys != null); @@ -824,7 +662,7 @@ namespace System.Collections.Generic } } - #endregion +#endregion #region ArraySortHelper for paired key and value arrays @@ -851,7 +689,6 @@ namespace System.Collections.Generic } } - [System.Security.SecuritySafeCritical] // auto-generated private static IArraySortHelper<TKey, TValue> CreateArraySortHelper() { if (typeof(IComparable<TKey>).IsAssignableFrom(typeof(TKey))) @@ -867,8 +704,8 @@ namespace System.Collections.Generic public void Sort(TKey[] keys, TValue[] values, int index, int length, IComparer<TKey> comparer) { - Contract.Assert(keys != null, "Check the arguments in the caller!"); // Precondition on interface method - Contract.Assert(index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!"); + Debug.Assert(keys != null, "Check the arguments in the caller!"); // Precondition on interface method + 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. @@ -879,22 +716,7 @@ namespace System.Collections.Generic comparer = Comparer<TKey>.Default; } -#if FEATURE_CORECLR - // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade - // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka - // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort. - IntrospectiveSort(keys, values, index, length, comparer); -#else - if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) - { - IntrospectiveSort(keys, values, index, length, comparer); - } - else - { - DepthLimitedQuickSort(keys, values, index, length + index - 1, comparer, IntrospectiveSortUtilities.QuickSortDepthThreshold); - } -#endif } catch (IndexOutOfRangeException) { @@ -947,68 +769,6 @@ namespace System.Collections.Generic } } - internal static void DepthLimitedQuickSort(TKey[] keys, TValue[] values, int left, int right, IComparer<TKey> comparer, int depthLimit) - { - do - { - if (depthLimit == 0) - { - Heapsort(keys, values, left, right, comparer); - return; - } - - int i = left; - int j = right; - - // pre-sort the low, middle (pivot), and high values in place. - // this improves performance in the face of already sorted data, or - // data that is made up of multiple sorted runs appended together. - int middle = i + ((j - i) >> 1); - SwapIfGreaterWithItems(keys, values, comparer, i, middle); // swap the low with the mid point - SwapIfGreaterWithItems(keys, values, comparer, i, j); // swap the low with the high - SwapIfGreaterWithItems(keys, values, comparer, middle, j); // swap the middle with the high - - TKey x = keys[middle]; - do - { - while (comparer.Compare(keys[i], x) < 0) i++; - while (comparer.Compare(x, keys[j]) < 0) j--; - Contract.Assert(i >= left && j <= right, "(i>=left && j<=right) Sort failed - Is your IComparer bogus?"); - if (i > j) break; - if (i < j) - { - TKey key = keys[i]; - keys[i] = keys[j]; - keys[j] = key; - if (values != null) - { - TValue value = values[i]; - values[i] = values[j]; - values[j] = value; - } - } - i++; - j--; - } while (i <= j); - - // The next iteration of the while loop is to "recursively" sort the larger half of the array and the - // following calls recursively sort the smaller half. So we subtract one from depthLimit here so - // both sorts see the new value. - depthLimit--; - - if (j - left <= right - i) - { - if (left < j) DepthLimitedQuickSort(keys, values, left, j, comparer, depthLimit); - left = i; - } - else - { - if (i < right) DepthLimitedQuickSort(keys, values, i, right, comparer, depthLimit); - right = j; - } - } while (left < right); - } - internal static void IntrospectiveSort(TKey[] keys, TValue[] values, int left, int length, IComparer<TKey> comparer) { Contract.Requires(keys != null); @@ -1199,8 +959,8 @@ namespace System.Collections.Generic { public void Sort(TKey[] keys, TValue[] values, int index, int length, IComparer<TKey> comparer) { - Contract.Assert(keys != null, "Check the arguments in the caller!"); - Contract.Assert( index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!"); + 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!"); // Add a try block here to detect IComparers (or their // underlying IComparables, etc) that are bogus. @@ -1208,44 +968,12 @@ namespace System.Collections.Generic { if (comparer == null || comparer == Comparer<TKey>.Default) { -#if FEATURE_CORECLR - // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade - // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka - // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort. - IntrospectiveSort(keys, values, index, length); -#else - // call the faster version of our sort algorithm if the user doesn't provide a comparer - if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) - { - IntrospectiveSort(keys, values, index, length); - } - else - { - DepthLimitedQuickSort(keys, values, index, length + index - 1, IntrospectiveSortUtilities.QuickSortDepthThreshold); - } -#endif } else { -#if FEATURE_CORECLR - // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade - // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka - // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort. - ArraySortHelper<TKey, TValue>.IntrospectiveSort(keys, values, index, length, comparer); -#else - if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) - { - ArraySortHelper<TKey, TValue>.IntrospectiveSort(keys, values, index, length, comparer); - } - else - { - ArraySortHelper<TKey, TValue>.DepthLimitedQuickSort(keys, values, index, length + index - 1, comparer, IntrospectiveSortUtilities.QuickSortDepthThreshold); - } -#endif } - } catch (IndexOutOfRangeException) { @@ -1292,80 +1020,6 @@ namespace System.Collections.Generic } } - private static void DepthLimitedQuickSort(TKey[] keys, TValue[] values, int left, int right, int depthLimit) - { - // The code in this function looks very similar to QuickSort in ArraySortHelper<T> class. - // The difference is that T is constrainted to IComparable<T> here. - // So the IL code will be different. This function is faster than the one in ArraySortHelper<T>. - - do - { - if (depthLimit == 0) - { - Heapsort(keys, values, left, right); - return; - } - - int i = left; - int j = right; - - // pre-sort the low, middle (pivot), and high values in place. - // this improves performance in the face of already sorted data, or - // data that is made up of multiple sorted runs appended together. - int middle = i + ((j - i) >> 1); - SwapIfGreaterWithItems(keys, values, i, middle); // swap the low with the mid point - SwapIfGreaterWithItems(keys, values, i, j); // swap the low with the high - SwapIfGreaterWithItems(keys, values, middle, j); // swap the middle with the high - - TKey x = keys[middle]; - do - { - if (x == null) - { - // if x null, the loop to find two elements to be switched can be reduced. - while (keys[j] != null) j--; - } - else - { - while (x.CompareTo(keys[i]) > 0) i++; - while (x.CompareTo(keys[j]) < 0) j--; - } - Contract.Assert(i >= left && j <= right, "(i>=left && j<=right) Sort failed - Is your IComparer bogus?"); - if (i > j) break; - if (i < j) - { - TKey key = keys[i]; - keys[i] = keys[j]; - keys[j] = key; - if (values != null) - { - TValue value = values[i]; - values[i] = values[j]; - values[j] = value; - } - } - i++; - j--; - } while (i <= j); - - // The next iteration of the while loop is to "recursively" sort the larger half of the array and the - // following calls recursively sort the smaller half. So we subtract one from depthLimit here so - // both sorts see the new value. - depthLimit--; - - if (j - left <= right - i) - { - if (left < j) DepthLimitedQuickSort(keys, values, left, j, depthLimit); - left = i; - } - else - { - if (i < right) DepthLimitedQuickSort(keys, values, i, right, depthLimit); - right = j; - } - } while (left < right); - } - internal static void IntrospectiveSort(TKey[] keys, TValue[] values, int left, int length) { Contract.Requires(keys != null); @@ -1554,5 +1208,3 @@ namespace System.Collections.Generic #endregion } - - diff --git a/src/mscorlib/src/System/Collections/Generic/Comparer.cs b/src/mscorlib/src/System/Collections/Generic/Comparer.cs index 9f1a8bff6f..4f06b0af69 100644 --- a/src/mscorlib/src/System/Collections/Generic/Comparer.cs +++ b/src/mscorlib/src/System/Collections/Generic/Comparer.cs @@ -7,6 +7,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.Contracts; //using System.Globalization; using System.Runtime.CompilerServices; @@ -33,7 +34,7 @@ namespace System.Collections.Generic Contract.Ensures(Contract.Result<Comparer<T>>() != null); if (comparison == null) - throw new ArgumentNullException("comparison"); + throw new ArgumentNullException(nameof(comparison)); return new ComparisonComparer<T>(comparison); } @@ -42,7 +43,6 @@ namespace System.Collections.Generic // Note that logic in this method is replicated in vm\compile.cpp to ensure that NGen // saves the right instantiations // - [System.Security.SecuritySafeCritical] // auto-generated private static Comparer<T> CreateComparer() { object result = null; @@ -139,7 +139,7 @@ namespace System.Collections.Generic [Serializable] internal sealed class NullableComparer<T> : Comparer<T?> where T : struct, IComparable<T> { - public override int Compare(Nullable<T> x, Nullable<T> y) { + public override int Compare(T? x, T? y) { if (x.HasValue) { if (y.HasValue) return x.value.CompareTo(y.value); return 1; @@ -196,7 +196,7 @@ namespace System.Collections.Generic { public Int32EnumComparer() { - Contract.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!"); + Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!"); } // Used by the serialization engine. @@ -216,7 +216,6 @@ namespace System.Collections.Generic public override int GetHashCode() => GetType().GetHashCode(); - [SecurityCritical] public void GetObjectData(SerializationInfo info, StreamingContext context) { // Previously Comparer<T> was not specialized for enums, @@ -232,7 +231,7 @@ namespace System.Collections.Generic { public UInt32EnumComparer() { - Contract.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!"); + Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!"); } // Used by the serialization engine. @@ -252,7 +251,6 @@ namespace System.Collections.Generic public override int GetHashCode() => GetType().GetHashCode(); - [SecurityCritical] public void GetObjectData(SerializationInfo info, StreamingContext context) { info.SetType(typeof(ObjectComparer<T>)); @@ -264,7 +262,7 @@ namespace System.Collections.Generic { public Int64EnumComparer() { - Contract.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!"); + Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!"); } // Used by the serialization engine. @@ -284,7 +282,6 @@ namespace System.Collections.Generic public override int GetHashCode() => GetType().GetHashCode(); - [SecurityCritical] public void GetObjectData(SerializationInfo info, StreamingContext context) { info.SetType(typeof(ObjectComparer<T>)); @@ -296,7 +293,7 @@ namespace System.Collections.Generic { public UInt64EnumComparer() { - Contract.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!"); + Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!"); } // Used by the serialization engine. @@ -316,7 +313,6 @@ namespace System.Collections.Generic public override int GetHashCode() => GetType().GetHashCode(); - [SecurityCritical] public void GetObjectData(SerializationInfo info, StreamingContext context) { info.SetType(typeof(ObjectComparer<T>)); diff --git a/src/mscorlib/src/System/Collections/Generic/DebugView.cs b/src/mscorlib/src/System/Collections/Generic/DebugView.cs index 57b91eff51..d0711e551e 100644 --- a/src/mscorlib/src/System/Collections/Generic/DebugView.cs +++ b/src/mscorlib/src/System/Collections/Generic/DebugView.cs @@ -110,7 +110,7 @@ namespace System.Collections.Generic { public Mscorlib_KeyedCollectionDebugView(KeyedCollection<K, T> keyedCollection) { if (keyedCollection == null) { - throw new ArgumentNullException("keyedCollection"); + throw new ArgumentNullException(nameof(keyedCollection)); } Contract.EndContractBlock(); diff --git a/src/mscorlib/src/System/Collections/Generic/Dictionary.cs b/src/mscorlib/src/System/Collections/Generic/Dictionary.cs index 9cbfff5a57..c2b2da9ad2 100644 --- a/src/mscorlib/src/System/Collections/Generic/Dictionary.cs +++ b/src/mscorlib/src/System/Collections/Generic/Dictionary.cs @@ -91,12 +91,12 @@ namespace System.Collections.Generic { if (capacity > 0) Initialize(capacity); this.comparer = comparer ?? EqualityComparer<TKey>.Default; -#if FEATURE_RANDOMIZED_STRING_HASHING && FEATURE_CORECLR +#if FEATURE_RANDOMIZED_STRING_HASHING if (HashHelpers.s_UseRandomizedStringHashing && comparer == EqualityComparer<string>.Default) { this.comparer = (IEqualityComparer<TKey>) NonRandomizedStringEqualityComparer.Default; } -#endif // FEATURE_RANDOMIZED_STRING_HASHING && FEATURE_CORECLR +#endif // FEATURE_RANDOMIZED_STRING_HASHING } public Dictionary(IDictionary<TKey,TValue> dictionary): this(dictionary, null) {} @@ -129,6 +129,21 @@ namespace System.Collections.Generic { } } + public Dictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection): + this(collection, null) { } + + public Dictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer): + this((collection as ICollection<KeyValuePair<TKey, TValue>>)?.Count ?? 0, comparer) + { + if (collection == null) { + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection); + } + + foreach (KeyValuePair<TKey, TValue> pair in collection) { + Add(pair.Key, pair.Value); + } + } + 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, @@ -263,7 +278,7 @@ namespace System.Collections.Generic { } if (index < 0 || index > array.Length ) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (array.Length - index < Count) { @@ -287,7 +302,6 @@ namespace System.Collections.Generic { return new Enumerator(this, Enumerator.KeyValuePair); } - [System.Security.SecurityCritical] // auto-generated_required public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { if (info==null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.info); @@ -347,11 +361,7 @@ namespace System.Collections.Generic { for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next) { if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) { if (add) { -#if FEATURE_CORECLR ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(key); -#else - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate); -#endif } entries[i].value = value; version++; @@ -386,8 +396,6 @@ namespace System.Collections.Generic { version++; #if FEATURE_RANDOMIZED_STRING_HASHING - -#if FEATURE_CORECLR // In case we hit the collision threshold we'll need to switch to the comparer which is using randomized string hashing // in this case will be EqualityComparer<string>.Default. // Note, randomized string hashing is turned on by default on coreclr so EqualityComparer<string>.Default will @@ -398,14 +406,6 @@ namespace System.Collections.Generic { comparer = (IEqualityComparer<TKey>) EqualityComparer<string>.Default; Resize(entries.Length, true); } -#else - if(collisionCount > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(comparer)) - { - comparer = (IEqualityComparer<TKey>) HashHelpers.GetRandomizedEqualityComparer(comparer); - Resize(entries.Length, true); - } -#endif // FEATURE_CORECLR - #endif } @@ -459,7 +459,7 @@ namespace System.Collections.Generic { } private void Resize(int newSize, bool forceNewHashCodes) { - Contract.Assert(newSize >= entries.Length); + 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]; @@ -523,16 +523,19 @@ namespace System.Collections.Generic { return false; } - // This is a convenience method for the internal callers that were converted from using Hashtable. - // Many were combining key doesn't exist and key exists but null value (for non-value types) checks. - // This allows them to continue getting that behavior with minimal code delta. This is basically - // TryGetValue without the out param - internal TValue GetValueOrDefault(TKey key) { + // Method similar to TryGetValue that returns the value instead of putting it in an out param. + public TValue GetValueOrDefault(TKey key) => GetValueOrDefault(key, default(TValue)); + + // Method similar to TryGetValue that returns the value instead of putting it in an out param. If the entry + // doesn't exist, returns the defaultValue instead. + public TValue GetValueOrDefault(TKey key, TValue defaultValue) + { int i = FindEntry(key); - if (i >= 0) { + if (i >= 0) + { return entries[i].value; } - return default(TValue); + return defaultValue; } bool ICollection<KeyValuePair<TKey,TValue>>.IsReadOnly { @@ -557,7 +560,7 @@ namespace System.Collections.Generic { } if (index < 0 || index > array.Length) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (array.Length - index < Count) { @@ -580,7 +583,7 @@ namespace System.Collections.Generic { else { object[] objects = array as object[]; if (objects == null) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } try { @@ -593,7 +596,7 @@ namespace System.Collections.Generic { } } catch(ArrayTypeMismatchException) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } } } @@ -733,7 +736,7 @@ namespace System.Collections.Generic { public bool MoveNext() { if (version != dictionary.version) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); } // Use unsigned comparison since we set index to dictionary.count+1 when the enumeration ends. @@ -762,7 +765,7 @@ namespace System.Collections.Generic { object IEnumerator.Current { get { if( index == 0 || (index == dictionary.count + 1)) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen(); } if (getEnumeratorRetType == DictEntry) { @@ -775,7 +778,7 @@ namespace System.Collections.Generic { void IEnumerator.Reset() { if (version != dictionary.version) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); } index = 0; @@ -785,7 +788,7 @@ namespace System.Collections.Generic { DictionaryEntry IDictionaryEnumerator.Entry { get { if( index == 0 || (index == dictionary.count + 1)) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen(); } return new DictionaryEntry(current.Key, current.Value); @@ -795,7 +798,7 @@ namespace System.Collections.Generic { object IDictionaryEnumerator.Key { get { if( index == 0 || (index == dictionary.count + 1)) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen(); } return current.Key; @@ -805,7 +808,7 @@ namespace System.Collections.Generic { object IDictionaryEnumerator.Value { get { if( index == 0 || (index == dictionary.count + 1)) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen(); } return current.Value; @@ -837,7 +840,7 @@ namespace System.Collections.Generic { } if (index < 0 || index > array.Length) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (array.Length - index < dictionary.Count) { @@ -898,7 +901,7 @@ namespace System.Collections.Generic { } if (index < 0 || index > array.Length) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (array.Length - index < dictionary.Count) { @@ -912,7 +915,7 @@ namespace System.Collections.Generic { else { object[] objects = array as object[]; if (objects == null) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } int count = dictionary.count; @@ -923,7 +926,7 @@ namespace System.Collections.Generic { } } catch(ArrayTypeMismatchException) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } } } @@ -956,7 +959,7 @@ namespace System.Collections.Generic { public bool MoveNext() { if (version != dictionary.version) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); } while ((uint)index < (uint)dictionary.count) { @@ -982,7 +985,7 @@ namespace System.Collections.Generic { Object System.Collections.IEnumerator.Current { get { if( index == 0 || (index == dictionary.count + 1)) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen(); } return currentKey; @@ -991,7 +994,7 @@ namespace System.Collections.Generic { void System.Collections.IEnumerator.Reset() { if (version != dictionary.version) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); } index = 0; @@ -1024,7 +1027,7 @@ namespace System.Collections.Generic { } if (index < 0 || index > array.Length) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (array.Length - index < dictionary.Count) { @@ -1085,7 +1088,7 @@ namespace System.Collections.Generic { } if (index < 0 || index > array.Length) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (array.Length - index < dictionary.Count) @@ -1098,7 +1101,7 @@ namespace System.Collections.Generic { else { object[] objects = array as object[]; if (objects == null) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } int count = dictionary.count; @@ -1109,7 +1112,7 @@ namespace System.Collections.Generic { } } catch(ArrayTypeMismatchException) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } } } @@ -1142,7 +1145,7 @@ namespace System.Collections.Generic { public bool MoveNext() { if (version != dictionary.version) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); } while ((uint)index < (uint)dictionary.count) { @@ -1167,7 +1170,7 @@ namespace System.Collections.Generic { Object System.Collections.IEnumerator.Current { get { if( index == 0 || (index == dictionary.count + 1)) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen(); } return currentValue; @@ -1176,7 +1179,7 @@ namespace System.Collections.Generic { void System.Collections.IEnumerator.Reset() { if (version != dictionary.version) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); } 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 b845d64fed..3731114119 100644 --- a/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs +++ b/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs @@ -32,7 +32,6 @@ namespace System.Collections.Generic // Note that logic in this method is replicated in vm\compile.cpp to ensure that NGen // saves the right instantiations // - [System.Security.SecuritySafeCritical] // auto-generated private static EqualityComparer<T> CreateComparer() { Contract.Ensures(Contract.Result<EqualityComparer<T>>() != null); @@ -144,10 +143,7 @@ namespace System.Collections.Generic } [Pure] - public override int GetHashCode(T obj) { - if (obj == null) return 0; - return obj.GetHashCode(); - } + public override int GetHashCode(T obj) => obj?.GetHashCode() ?? 0; internal override int IndexOf(T[] array, T value, int startIndex, int count) { int endIndex = startIndex + count; @@ -179,22 +175,21 @@ namespace System.Collections.Generic return -1; } - // Equals method for the comparer itself. - public override bool Equals(Object obj){ - GenericEqualityComparer<T> comparer = obj as GenericEqualityComparer<T>; - return comparer != null; - } + // Equals method for the comparer itself. + // If in the future this type is made sealed, change the is check to obj != null && GetType() == obj.GetType(). + public override bool Equals(Object obj) => + obj is GenericEqualityComparer<T>; - public override int GetHashCode() { - return this.GetType().Name.GetHashCode(); - } + // If in the future this type is made sealed, change typeof(...) to GetType(). + public override int GetHashCode() => + typeof(GenericEqualityComparer<T>).GetHashCode(); } [Serializable] - internal class NullableEqualityComparer<T> : EqualityComparer<Nullable<T>> where T : struct, IEquatable<T> + internal sealed class NullableEqualityComparer<T> : EqualityComparer<T?> where T : struct, IEquatable<T> { [Pure] - public override bool Equals(Nullable<T> x, Nullable<T> y) { + public override bool Equals(T? x, T? y) { if (x.HasValue) { if (y.HasValue) return x.value.Equals(y.value); return false; @@ -204,11 +199,9 @@ namespace System.Collections.Generic } [Pure] - public override int GetHashCode(Nullable<T> obj) { - return obj.GetHashCode(); - } + public override int GetHashCode(T? obj) => obj.GetHashCode(); - internal override int IndexOf(Nullable<T>[] array, Nullable<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++) { @@ -223,7 +216,7 @@ namespace System.Collections.Generic return -1; } - internal override int LastIndexOf(Nullable<T>[] array, Nullable<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--) { @@ -238,19 +231,16 @@ namespace System.Collections.Generic return -1; } - // Equals method for the comparer itself. - public override bool Equals(Object obj){ - NullableEqualityComparer<T> comparer = obj as NullableEqualityComparer<T>; - return comparer != null; - } + // Equals method for the comparer itself. + public override bool Equals(Object obj) => + obj != null && GetType() == obj.GetType(); - public override int GetHashCode() { - return this.GetType().Name.GetHashCode(); - } + public override int GetHashCode() => + GetType().GetHashCode(); } [Serializable] - internal class ObjectEqualityComparer<T>: EqualityComparer<T> + internal sealed class ObjectEqualityComparer<T>: EqualityComparer<T> { [Pure] public override bool Equals(T x, T y) { @@ -263,10 +253,7 @@ namespace System.Collections.Generic } [Pure] - public override int GetHashCode(T obj) { - if (obj == null) return 0; - return obj.GetHashCode(); - } + public override int GetHashCode(T obj) => obj?.GetHashCode() ?? 0; internal override int IndexOf(T[] array, T value, int startIndex, int count) { int endIndex = startIndex + count; @@ -298,25 +285,21 @@ namespace System.Collections.Generic return -1; } - // Equals method for the comparer itself. - public override bool Equals(Object obj){ - ObjectEqualityComparer<T> comparer = obj as ObjectEqualityComparer<T>; - return comparer != null; - } + // Equals method for the comparer itself. + public override bool Equals(Object obj) => + obj != null && GetType() == obj.GetType(); - public override int GetHashCode() { - return this.GetType().Name.GetHashCode(); - } + public override int GetHashCode() => + GetType().GetHashCode(); } -#if FEATURE_CORECLR // NonRandomizedStringEqualityComparer is the comparer used by default with the Dictionary<string,...> // As the randomized string hashing is turned on by default on coreclr, we need to keep the performance not affected // as much as possible in the main stream scenarios like Dictionary<string,> // We use NonRandomizedStringEqualityComparer as default comparer as it doesnt use the randomized string hashing which // 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; @@ -335,12 +318,11 @@ namespace System.Collections.Generic return obj.GetLegacyNonRandomizedHashCode(); } } -#endif // FEATURE_CORECLR // 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 class ByteEqualityComparer: EqualityComparer<byte> + internal sealed class ByteEqualityComparer: EqualityComparer<byte> { [Pure] public override bool Equals(byte x, byte y) { @@ -352,14 +334,13 @@ namespace System.Collections.Generic return b.GetHashCode(); } - [System.Security.SecuritySafeCritical] // auto-generated internal unsafe override int IndexOf(byte[] array, byte value, int startIndex, int count) { if (array==null) - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); if (startIndex < 0) - throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index")); if (count < 0) - throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count")); + throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count")); if (count > array.Length - startIndex) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -377,15 +358,12 @@ namespace System.Collections.Generic return -1; } - // Equals method for the comparer itself. - public override bool Equals(Object obj){ - ByteEqualityComparer comparer = obj as ByteEqualityComparer; - return comparer != null; - } + // Equals method for the comparer itself. + public override bool Equals(Object obj) => + obj != null && GetType() == obj.GetType(); - public override int GetHashCode() { - return this.GetType().Name.GetHashCode(); - } + public override int GetHashCode() => + GetType().GetHashCode(); } [Serializable] @@ -409,7 +387,6 @@ namespace System.Collections.Generic // This is used by the serialization engine. protected EnumEqualityComparer(SerializationInfo information, StreamingContext context) { } - [SecurityCritical] public void GetObjectData(SerializationInfo info, StreamingContext context) { // For back-compat we need to serialize the comparers for enums with underlying types other than int as ObjectEqualityComparer if (Type.GetTypeCode(Enum.GetUnderlyingType(typeof(T))) != TypeCode.Int32) { @@ -417,14 +394,35 @@ namespace System.Collections.Generic } } - // Equals method for the comparer itself. - public override bool Equals(Object obj){ - EnumEqualityComparer<T> comparer = obj as EnumEqualityComparer<T>; - return comparer != null; + // Equals method for the comparer itself. + public override bool Equals(Object obj) => + obj != null && GetType() == obj.GetType(); + + public override int GetHashCode() => + GetType().GetHashCode(); + + internal override int IndexOf(T[] array, T value, int startIndex, int count) + { + int toFind = JitHelpers.UnsafeEnumCast(value); + int endIndex = startIndex + count; + for (int i = startIndex; i < endIndex; i++) + { + int current = JitHelpers.UnsafeEnumCast(array[i]); + if (toFind == current) return i; + } + return -1; } - public override int GetHashCode() { - return this.GetType().Name.GetHashCode(); + internal override int LastIndexOf(T[] array, T value, int startIndex, int count) + { + int toFind = JitHelpers.UnsafeEnumCast(value); + int endIndex = startIndex - count + 1; + for (int i = startIndex; i >= endIndex; i--) + { + int current = JitHelpers.UnsafeEnumCast(array[i]); + if (toFind == current) return i; + } + return -1; } } @@ -474,28 +472,48 @@ namespace System.Collections.Generic return x_final.GetHashCode(); } - // Equals method for the comparer itself. - public override bool Equals(Object obj){ - LongEnumEqualityComparer<T> comparer = obj as LongEnumEqualityComparer<T>; - return comparer != null; - } + // Equals method for the comparer itself. + public override bool Equals(Object obj) => + obj != null && GetType() == obj.GetType(); - public override int GetHashCode() { - return this.GetType().Name.GetHashCode(); - } + public override int GetHashCode() => + GetType().GetHashCode(); public LongEnumEqualityComparer() { } // This is used by the serialization engine. public LongEnumEqualityComparer(SerializationInfo information, StreamingContext context) { } - [SecurityCritical] public void GetObjectData(SerializationInfo info, StreamingContext context) { // The LongEnumEqualityComparer does not exist on 4.0 so we need to serialize this comparer as ObjectEqualityComparer // to allow for roundtrip between 4.0 and 4.5. info.SetType(typeof(ObjectEqualityComparer<T>)); } + + internal override int IndexOf(T[] array, T value, int startIndex, int count) + { + long toFind = JitHelpers.UnsafeEnumCastLong(value); + int endIndex = startIndex + count; + for (int i = startIndex; i < endIndex; i++) + { + long current = JitHelpers.UnsafeEnumCastLong(array[i]); + if (toFind == current) return i; + } + return -1; + } + + internal override int LastIndexOf(T[] array, T value, int startIndex, int count) + { + long toFind = JitHelpers.UnsafeEnumCastLong(value); + int endIndex = startIndex - count + 1; + for (int i = startIndex; i >= endIndex; i--) + { + long current = JitHelpers.UnsafeEnumCastLong(array[i]); + if (toFind == current) return i; + } + return -1; + } } #if FEATURE_RANDOMIZED_STRING_HASHING @@ -528,14 +546,12 @@ namespace System.Collections.Generic } [Pure] - [SecuritySafeCritical] public int GetHashCode(String obj) { if(obj == null) return 0; return String.InternalMarvin32HashString(obj, obj.Length, _entropy); } [Pure] - [SecuritySafeCritical] public int GetHashCode(Object obj) { if(obj == null) return 0; @@ -552,7 +568,7 @@ namespace System.Collections.Generic } public override int GetHashCode() { - return (this.GetType().Name.GetHashCode() ^ ((int) (_entropy & 0x7FFFFFFF))); + return (this.GetType().GetHashCode() ^ ((int) (_entropy & 0x7FFFFFFF))); } @@ -587,7 +603,6 @@ namespace System.Collections.Generic } [Pure] - [SecuritySafeCritical] public int GetHashCode(Object obj) { if(obj == null) return 0; @@ -604,7 +619,7 @@ namespace System.Collections.Generic } public override int GetHashCode() { - return (this.GetType().Name.GetHashCode() ^ ((int) (_entropy & 0x7FFFFFFF))); + return (this.GetType().GetHashCode() ^ ((int) (_entropy & 0x7FFFFFFF))); } IEqualityComparer IWellKnownStringEqualityComparer.GetRandomizedEqualityComparer() { diff --git a/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs b/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs index 17e1c531f1..ad9f7472aa 100644 --- a/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs +++ b/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs @@ -18,6 +18,16 @@ namespace System.Collections.Generic { using System; 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>. @@ -52,5 +62,12 @@ namespace System.Collections.Generic { s.Append(']'); return StringBuilderCache.GetStringAndRelease(s); } + + // BLOCKED (do not add now): [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 ae3356d372..3e2947f5f9 100644 --- a/src/mscorlib/src/System/Collections/Generic/List.cs +++ b/src/mscorlib/src/System/Collections/Generic/List.cs @@ -91,14 +91,7 @@ namespace System.Collections.Generic { else { _size = 0; _items = _emptyArray; - // This enumerable could be empty. Let Add allocate a new array, if needed. - // Note it will also go to _defaultCapacity first, not 1, then 2, etc. - - using(IEnumerator<T> en = collection.GetEnumerator()) { - while(en.MoveNext()) { - Add(en.Current); - } - } + AddEnumerable(collection); } } @@ -274,7 +267,7 @@ namespace System.Collections.Generic { // public int BinarySearch(int index, int count, T item, IComparer<T> comparer) { if (index < 0) - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); if (count < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); if (_size - index < count) @@ -369,7 +362,7 @@ namespace System.Collections.Generic { Array.Copy(_items, 0, array, arrayIndex, _size); } catch(ArrayTypeMismatchException){ - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } } @@ -393,7 +386,7 @@ namespace System.Collections.Generic { } // Ensures that the capacity of this list is at least the given minimum - // value. If the currect capacity of the list is less than min, the + // 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) { @@ -454,11 +447,11 @@ namespace System.Collections.Generic { public int FindIndex(int startIndex, int count, Predicate<T> match) { if( (uint)startIndex > (uint)_size ) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index); + ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index(); } if (count < 0 || startIndex > _size - count) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count); + ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count(); } if( match == null) { @@ -512,19 +505,19 @@ namespace System.Collections.Generic { if(_size == 0) { // Special case for 0 length List if( startIndex != -1) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index); + ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index(); } } else { // Make sure we're not out of range if ( (uint)startIndex >= (uint)_size) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index); + 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) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count); + ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count(); } int endIndex = startIndex - count; @@ -545,14 +538,14 @@ namespace System.Collections.Generic { int version = _version; for(int i = 0 ; i < _size; i++) { - if (version != _version && BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) { + if (version != _version) { break; } action(_items[i]); } - if (version != _version && BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); + if (version != _version) + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); } // Returns an enumerator for this list with the given @@ -575,7 +568,7 @@ namespace System.Collections.Generic { public List<T> GetRange(int index, int count) { if (index < 0) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (count < 0) { @@ -628,7 +621,7 @@ namespace System.Collections.Generic { // public int IndexOf(T item, int index) { if (index > _size) - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index); + ThrowHelper.ThrowArgumentOutOfRange_IndexException(); Contract.Ensures(Contract.Result<int>() >= -1); Contract.Ensures(Contract.Result<int>() < Count); Contract.EndContractBlock(); @@ -646,9 +639,9 @@ namespace System.Collections.Generic { // public int IndexOf(T item, int index, int count) { if (index > _size) - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index); + ThrowHelper.ThrowArgumentOutOfRange_IndexException(); - if (count <0 || index > _size - count) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.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(); @@ -698,7 +691,7 @@ namespace System.Collections.Generic { } if ((uint)index > (uint)_size) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index); + ThrowHelper.ThrowArgumentOutOfRange_IndexException(); } Contract.EndContractBlock(); @@ -719,20 +712,24 @@ namespace System.Collections.Generic { Array.Copy(_items, index+count, _items, index*2, _size-index); } else { - T[] itemsToInsert = new T[count]; - c.CopyTo(itemsToInsert, 0); - itemsToInsert.CopyTo(_items, index); + c.CopyTo(_items, index); } _size += count; } } - else { + 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); } } } + else + { + // We're adding a lazy enumerable because the index is at the end of this list. + AddEnumerable(collection); + } _version++; } @@ -768,7 +765,7 @@ namespace System.Collections.Generic { public int LastIndexOf(T item, int index) { if (index >= _size) - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index); + ThrowHelper.ThrowArgumentOutOfRange_IndexException(); Contract.Ensures(Contract.Result<int>() >= -1); Contract.Ensures(((Count == 0) && (Contract.Result<int>() == -1)) || ((Count > 0) && (Contract.Result<int>() <= index))); Contract.EndContractBlock(); @@ -786,7 +783,7 @@ namespace System.Collections.Generic { // public int LastIndexOf(T item, int index, int count) { if ((Count != 0) && (index < 0)) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if ((Count !=0) && (count < 0)) { @@ -885,7 +882,7 @@ namespace System.Collections.Generic { // public void RemoveRange(int index, int count) { if (index < 0) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (count < 0) { @@ -919,7 +916,7 @@ namespace System.Collections.Generic { // public void Reverse(int index, int count) { if (index < 0) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (count < 0) { @@ -930,22 +927,7 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen); Contract.EndContractBlock(); - // The non-generic Array.Reverse is not used because it does not perform - // well for non-primitive value types. - // If/when a generic Array.Reverse<T> becomes available, the below code - // can be deleted and replaced with a call to Array.Reverse<T>. - int i = index; - int j = index + count - 1; - T[] array = _items; - while (i < j) - { - T temp = array[i]; - array[i] = array[j]; - array[j] = temp; - i++; - j--; - } - + Array.Reverse(_items, index, count); _version++; } @@ -973,7 +955,7 @@ namespace System.Collections.Generic { // public void Sort(int index, int count, IComparer<T> comparer) { if (index < 0) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (count < 0) { @@ -995,8 +977,7 @@ namespace System.Collections.Generic { Contract.EndContractBlock(); if( _size > 0) { - IComparer<T> comparer = Comparer<T>.Create(comparison); - Array.Sort(_items, 0, _size, comparer); + ArraySortHelper<T>.Sort(_items, 0, _size, comparison); } } @@ -1006,12 +987,10 @@ namespace System.Collections.Generic { Contract.Ensures(Contract.Result<T[]>() != null); Contract.Ensures(Contract.Result<T[]>().Length == Count); -#if FEATURE_CORECLR if (_size == 0) { return _emptyArray; } -#endif T[] array = new T[_size]; Array.Copy(_items, 0, array, 0, _size); @@ -1048,6 +1027,31 @@ namespace System.Collections.Generic { return true; } + private void AddEnumerable(IEnumerable<T> enumerable) + { + Debug.Assert(enumerable != null); + Debug.Assert(!(enumerable is ICollection<T>), "We should have optimized for this beforehand."); + + using (IEnumerator<T> en = enumerable.GetEnumerator()) + { + _version++; // Even if the enumerable has no items, we can update _version. + + while (en.MoveNext()) + { + // Capture Current before doing anything else. If this throws + // an exception, we want to make a clean break. + T current = en.Current; + + if (_size == _items.Length) + { + EnsureCapacity(_size + 1); + } + + _items[_size++] = current; + } + } + } + [Serializable] public struct Enumerator : IEnumerator<T>, System.Collections.IEnumerator { @@ -1082,7 +1086,7 @@ namespace System.Collections.Generic { private bool MoveNextRare() { if (version != list._version) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); } index = list._size + 1; @@ -1099,7 +1103,7 @@ namespace System.Collections.Generic { Object System.Collections.IEnumerator.Current { get { if( index == 0 || index == list._size + 1) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen(); } return Current; } @@ -1107,7 +1111,7 @@ namespace System.Collections.Generic { void System.Collections.IEnumerator.Reset() { if (version != list._version) { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); } index = 0; diff --git a/src/mscorlib/src/System/Collections/Hashtable.cs b/src/mscorlib/src/System/Collections/Hashtable.cs index 262ccedea6..d4c7d8d673 100644 --- a/src/mscorlib/src/System/Collections/Hashtable.cs +++ b/src/mscorlib/src/System/Collections/Hashtable.cs @@ -23,10 +23,7 @@ namespace System.Collections { using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Diagnostics.Contracts; -#if !FEATURE_CORECLR - using System.Security.Cryptography; -#endif - + // The Hashtable class represents a dictionary of associated keys and values // with constant lookup time. // @@ -271,9 +268,9 @@ namespace System.Collections { // public Hashtable(int capacity, float loadFactor) { if (capacity < 0) - throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (!(loadFactor >= 0.1f && loadFactor <= 1.0f)) - throw new ArgumentOutOfRangeException("loadFactor", Environment.GetResourceString("ArgumentOutOfRange_HashtableLoadFactor", .1, 1.0)); + throw new ArgumentOutOfRangeException(nameof(loadFactor), Environment.GetResourceString("ArgumentOutOfRange_HashtableLoadFactor", .1, 1.0)); Contract.EndContractBlock(); // Based on perf work, .72 is the optimal load factor for this table. @@ -290,7 +287,7 @@ namespace System.Collections { loadsize = (int)(this.loadFactor * hashsize); isWriterInProgress = false; // Based on the current algorithm, loadsize must be less than hashsize. - Contract.Assert( loadsize < hashsize, "Invalid hashtable loadsize!"); + Debug.Assert( loadsize < hashsize, "Invalid hashtable loadsize!"); } // Constructs a new hashtable with the given initial capacity and load @@ -375,7 +372,7 @@ namespace System.Collections { public Hashtable(IDictionary d, float loadFactor, IHashCodeProvider hcp, IComparer comparer) : this((d != null ? d.Count : 0), loadFactor, hcp, comparer) { if (d==null) - throw new ArgumentNullException("d", Environment.GetResourceString("ArgumentNull_Dictionary")); + throw new ArgumentNullException(nameof(d), Environment.GetResourceString("ArgumentNull_Dictionary")); Contract.EndContractBlock(); IDictionaryEnumerator e = d.GetEnumerator(); @@ -385,7 +382,7 @@ namespace System.Collections { public Hashtable(IDictionary d, float loadFactor, IEqualityComparer equalityComparer) : this((d != null ? d.Count : 0), loadFactor, equalityComparer) { if (d==null) - throw new ArgumentNullException("d", Environment.GetResourceString("ArgumentNull_Dictionary")); + throw new ArgumentNullException(nameof(d), Environment.GetResourceString("ArgumentNull_Dictionary")); Contract.EndContractBlock(); IDictionaryEnumerator e = d.GetEnumerator(); @@ -444,14 +441,11 @@ namespace System.Collections { // Removes all entries from this hashtable. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] public virtual void Clear() { - Contract.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."); + 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; -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif isWriterInProgress = true; for (int i = 0; i < buckets.Length; i++){ buckets[i].hash_coll = 0; @@ -463,9 +457,6 @@ namespace System.Collections { occupancy = 0; UpdateVersion(); isWriterInProgress = false; -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif } // Clone returns a virtually identical copy of this hash table. This does @@ -501,7 +492,7 @@ namespace System.Collections { // public virtual bool ContainsKey(Object key) { if (key == null) { - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); } Contract.EndContractBlock(); @@ -526,9 +517,7 @@ namespace System.Collections { } while (b.hash_coll < 0 && ++ntry < lbuckets.Length); return false; } - - - + // Checks if this hashtable contains an entry with the given value. The // values of the entries of the hashtable are compared to the given value // using the Object.Equals method. This method performs a linear @@ -590,11 +579,11 @@ namespace System.Collections { public virtual void CopyTo(Array array, int arrayIndex) { if (array == null) - throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Array")); + throw new ArgumentNullException(nameof(array), Environment.GetResourceString("ArgumentNull_Array")); if (array.Rank != 1) throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported")); if (arrayIndex < 0) - throw new ArgumentOutOfRangeException("arrayIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (array.Length - arrayIndex < Count) throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall")); Contract.EndContractBlock(); @@ -643,7 +632,7 @@ namespace System.Collections { public virtual Object this[Object key] { get { if (key == null) { - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); } Contract.EndContractBlock(); @@ -750,28 +739,23 @@ namespace System.Collections { for (nb = 0; nb < buckets.Length; nb++){ bucket oldb = buckets[nb]; if ((oldb.key != null) && (oldb.key != buckets)) { - int hashcode = ((forceNewHashCode ? GetHash(oldb.key) : oldb.hash_coll) & 0x7FFFFFFF); + int hashcode = ((forceNewHashCode ? GetHash(oldb.key) : oldb.hash_coll) & 0x7FFFFFFF); putEntry(newBuckets, oldb.key, oldb.val, hashcode); } } - + // New bucket[] is good to go - replace buckets and other internal state. -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif isWriterInProgress = true; buckets = newBuckets; loadsize = (int)(loadFactor * newsize); UpdateVersion(); isWriterInProgress = false; -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif + // minimun size of hashtable is 3 now and maximum loadFactor is 0.72 now. - Contract.Assert(loadsize < newsize, "Our current implementaion means this is not possible."); + Debug.Assert(loadsize < newsize, "Our current implementaion means this is not possible."); return; } - + // Returns an enumerator for this hashtable. // If modifications made to the hashtable while an enumeration is // in progress, the MoveNext and Current methods of the @@ -820,7 +804,7 @@ namespace System.Collections { // protected virtual bool KeyEquals(Object item, Object key) { - Contract.Assert(key != null, "key can't be null here!"); + Debug.Assert(key != null, "key can't be null here!"); if( Object.ReferenceEquals(buckets, item)) { return false; } @@ -872,7 +856,7 @@ namespace System.Collections { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private void Insert (Object key, Object nvalue, bool add) { if (key == null) { - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); } Contract.EndContractBlock(); if (count >= loadsize) { @@ -913,36 +897,14 @@ namespace System.Collections { // We pretty much have to insert in this order. Don't set hash // code until the value & key are set appropriately. -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif - isWriterInProgress = true; + isWriterInProgress = true; buckets[bucketNumber].val = nvalue; buckets[bucketNumber].key = key; buckets[bucketNumber].hash_coll |= (int) hashcode; count++; UpdateVersion(); isWriterInProgress = false; -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif -#if FEATURE_RANDOMIZED_STRING_HASHING -#if !FEATURE_CORECLR - // coreclr has the randomized string hashing on by default so we don't need to resize at this point - - if(ntry > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(_keycomparer)) - { - // PERF: We don't want to rehash if _keycomparer is already a RandomizedObjectEqualityComparer since in some - // cases there may not be any strings in the hashtable and we wouldn't get any mixing. - if(_keycomparer == null || !(_keycomparer is System.Collections.Generic.RandomizedObjectEqualityComparer)) - { - _keycomparer = HashHelpers.GetRandomizedEqualityComparer(_keycomparer); - rehash(buckets.Length, true); - } - } -#endif // !FEATURE_CORECLR -#endif // FEATURE_RANDOMIZED_STRING_HASHING return; } @@ -954,31 +916,10 @@ namespace System.Collections { if (add) { throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate__", buckets[bucketNumber].key, key)); } -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif - isWriterInProgress = true; + isWriterInProgress = true; buckets[bucketNumber].val = nvalue; - UpdateVersion(); + UpdateVersion(); isWriterInProgress = false; -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif - -#if FEATURE_RANDOMIZED_STRING_HASHING -#if !FEATURE_CORECLR - if(ntry > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(_keycomparer)) - { - // PERF: We don't want to rehash if _keycomparer is already a RandomizedObjectEqualityComparer since in some - // cases there may not be any strings in the hashtable and we wouldn't get any mixing. - if(_keycomparer == null || !(_keycomparer is System.Collections.Generic.RandomizedObjectEqualityComparer)) - { - _keycomparer = HashHelpers.GetRandomizedEqualityComparer(_keycomparer); - rehash(buckets.Length, true); - } - } -#endif // !FEATURE_CORECLR -#endif return; } @@ -992,7 +933,7 @@ namespace System.Collections { } } - 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 @@ -1000,47 +941,27 @@ namespace System.Collections { { // We pretty much have to insert in this order. Don't set hash // code until the value & key are set appropriately. -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif - isWriterInProgress = true; + isWriterInProgress = true; buckets[emptySlotNumber].val = nvalue; buckets[emptySlotNumber].key = key; buckets[emptySlotNumber].hash_coll |= (int) hashcode; count++; UpdateVersion(); isWriterInProgress = false; -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif -#if FEATURE_RANDOMIZED_STRING_HASHING -#if !FEATURE_CORECLR - if(buckets.Length > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(_keycomparer)) - { - // PERF: We don't want to rehash if _keycomparer is already a RandomizedObjectEqualityComparer since in some - // cases there may not be any strings in the hashtable and we wouldn't get any mixing. - if(_keycomparer == null || !(_keycomparer is System.Collections.Generic.RandomizedObjectEqualityComparer)) - { - _keycomparer = HashHelpers.GetRandomizedEqualityComparer(_keycomparer); - rehash(buckets.Length, true); - } - } -#endif // !FEATURE_CORECLR -#endif return; } - + // If you see this assert, make sure load factor & count are reasonable. // Then verify that our double hash function (h2, described at top of file) // meets the requirements described above. You should never see this assert. - Contract.Assert(false, "hash table insert failed! Load factor too high, or our double hashing function is incorrect."); + 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")); } private void putEntry (bucket[] newBuckets, Object key, Object nvalue, int hashcode) { - Contract.Assert(hashcode >= 0, "hashcode >= 0"); // make sure collision bit (sign bit) wasn't set. + Debug.Assert(hashcode >= 0, "hashcode >= 0"); // make sure collision bit (sign bit) wasn't set. uint seed = (uint) hashcode; uint incr = (uint)(1 + ((seed * HashPrime) % ((uint)newBuckets.Length - 1))); @@ -1058,7 +979,7 @@ namespace System.Collections { 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); } @@ -1069,10 +990,10 @@ namespace System.Collections { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public virtual void Remove(Object key) { if (key == null) { - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); } Contract.EndContractBlock(); - Contract.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."); + 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."); uint seed; uint incr; @@ -1086,9 +1007,6 @@ namespace System.Collections { b = buckets[bn]; if (((b.hash_coll & 0x7FFFFFFF) == hashcode) && KeyEquals (b.key, key)) { -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif isWriterInProgress = true; // Clear hash_coll field, then key, then value buckets[bn].hash_coll &= unchecked((int)0x80000000); @@ -1102,12 +1020,9 @@ namespace System.Collections { count--; UpdateVersion(); isWriterInProgress = false; -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif 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")); @@ -1131,10 +1046,9 @@ namespace System.Collections { // Returns a thread-safe wrapper for a Hashtable. // - [HostProtection(Synchronization=true)] public static Hashtable Synchronized(Hashtable table) { if (table==null) - throw new ArgumentNullException("table"); + throw new ArgumentNullException(nameof(table)); Contract.EndContractBlock(); return new SyncHashtable(table); } @@ -1143,10 +1057,9 @@ namespace System.Collections { // The ISerializable Implementation // - [System.Security.SecurityCritical] public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { if (info==null) { - throw new ArgumentNullException("info"); + throw new ArgumentNullException(nameof(info)); } Contract.EndContractBlock(); // This is imperfect - it only works well if all other writes are @@ -1302,11 +1215,11 @@ namespace System.Collections { public virtual void CopyTo(Array array, int arrayIndex) { if (array==null) - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); if (array.Rank != 1) throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported")); if (arrayIndex < 0) - throw new ArgumentOutOfRangeException("arrayIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); if (array.Length - arrayIndex < _hashtable.count) throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall")); @@ -1343,11 +1256,11 @@ namespace System.Collections { public virtual void CopyTo(Array array, int arrayIndex) { if (array==null) - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); if (array.Rank != 1) throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported")); if (arrayIndex < 0) - throw new ArgumentOutOfRangeException("arrayIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); if (array.Length - arrayIndex < _hashtable.count) throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall")); @@ -1399,10 +1312,9 @@ namespace System.Collections { ** context -- the StreamingContext for the current serialization (ignored) **Exceptions: ArgumentNullException if info is null. ==============================================================================*/ - [System.Security.SecurityCritical] // auto-generated public override void GetObjectData(SerializationInfo info, StreamingContext context) { if (info==null) { - throw new ArgumentNullException("info"); + throw new ArgumentNullException(nameof(info)); } Contract.EndContractBlock(); // Our serialization code hasn't been fully tweaked to be safe @@ -1461,7 +1373,7 @@ namespace System.Collections { public override bool ContainsKey(Object key) { if (key == null) { - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); } Contract.EndContractBlock(); return _table.ContainsKey(key); @@ -1630,7 +1542,7 @@ namespace System.Collections { public HashtableDebugView( Hashtable hashtable) { if( hashtable == null) { - throw new ArgumentNullException( "hashtable"); + throw new ArgumentNullException(nameof(hashtable)); } Contract.EndContractBlock(); @@ -1746,7 +1658,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) { - Contract.Assert( MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength"); + Debug.Assert( MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength"); return MaxPrimeArrayLength; } @@ -1765,7 +1677,7 @@ namespace System.Collections { public static IEqualityComparer GetRandomizedEqualityComparer(object comparer) { - Contract.Assert(comparer == null || comparer == System.Collections.Generic.EqualityComparer<string>.Default || comparer is IWellKnownStringEqualityComparer); + Debug.Assert(comparer == null || comparer == System.Collections.Generic.EqualityComparer<string>.Default || comparer is IWellKnownStringEqualityComparer); if(comparer == null) { return new System.Collections.Generic.RandomizedObjectEqualityComparer(); @@ -1781,7 +1693,7 @@ namespace System.Collections { return cmp.GetRandomizedEqualityComparer(); } - Contract.Assert(false, "Missing case in GetRandomizedEqualityComparer!"); + Debug.Assert(false, "Missing case in GetRandomizedEqualityComparer!"); return null; } @@ -1804,9 +1716,6 @@ namespace System.Collections { } private const int bufferSize = 1024; -#if !FEATURE_CORECLR - private static RandomNumberGenerator rng; -#endif private static byte[] data; private static int currentIndex = bufferSize; private static readonly object lockObj = new Object(); @@ -1821,18 +1730,10 @@ namespace System.Collections { if(data == null) { data = new byte[bufferSize]; - Contract.Assert(bufferSize % 8 == 0, "We increment our current index by 8, so our buffer size must be a multiple of 8"); -#if !FEATURE_CORECLR - rng = RandomNumberGenerator.Create(); -#endif - + Debug.Assert(bufferSize % 8 == 0, "We increment our current index by 8, so our buffer size must be a multiple of 8"); } -#if FEATURE_CORECLR Microsoft.Win32.Win32Native.Random(true, data, data.Length); -#else - rng.GetBytes(data); -#endif currentIndex = 0; } diff --git a/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs b/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs index 944523c475..be5490b194 100644 --- a/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs +++ b/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs @@ -30,7 +30,7 @@ namespace System.Collections { public Object this[Object key] { get { if (key == null) { - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); } Contract.EndContractBlock(); DictionaryNode node = head; @@ -45,16 +45,16 @@ namespace System.Collections { } set { if (key == null) { - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); } Contract.EndContractBlock(); #if FEATURE_SERIALIZATION if (!key.GetType().IsSerializable) - throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "key"); + throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(key)); if( (value != null) && (!value.GetType().IsSerializable ) ) - throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "value"); + throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(value)); #endif version++; @@ -132,16 +132,16 @@ namespace System.Collections { public void Add(Object key, Object value) { if (key == null) { - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); } Contract.EndContractBlock(); #if FEATURE_SERIALIZATION if (!key.GetType().IsSerializable) - throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "key" ); + throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(key) ); if( (value != null) && (!value.GetType().IsSerializable) ) - throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "value"); + throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(value)); #endif version++; @@ -179,7 +179,7 @@ namespace System.Collections { public bool Contains(Object key) { if (key == null) { - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); } Contract.EndContractBlock(); for (DictionaryNode node = head; node != null; node = node.next) { @@ -192,16 +192,16 @@ namespace System.Collections { public void CopyTo(Array array, int index) { if (array==null) - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); if (array.Rank != 1) throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported")); if (index < 0) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if ( array.Length - index < this.Count ) - throw new ArgumentException( Environment.GetResourceString("ArgumentOutOfRange_Index"), "index"); + throw new ArgumentException( Environment.GetResourceString("ArgumentOutOfRange_Index"), nameof(index)); Contract.EndContractBlock(); for (DictionaryNode node = head; node != null; node = node.next) { @@ -220,7 +220,7 @@ namespace System.Collections { public void Remove(Object key) { if (key == null) { - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); } Contract.EndContractBlock(); version++; @@ -328,14 +328,14 @@ namespace System.Collections { void ICollection.CopyTo(Array array, int index) { if (array==null) - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); if (array.Rank != 1) throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported")); if (index < 0) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); if (array.Length - index < list.Count) - throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Index"), "index"); + throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Index"), nameof(index)); for (DictionaryNode node = list.head; node != null; node = node.next) { array.SetValue(isKeys ? node.key : node.value, index); index++; diff --git a/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs b/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs index 54aa7bb09d..a3804ad7ab 100644 --- a/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs +++ b/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs @@ -183,7 +183,7 @@ namespace System.Collections.ObjectModel } if (index < 0 ) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (array.Length - index < Count) { @@ -204,7 +204,7 @@ namespace System.Collections.ObjectModel Type targetType = array.GetType().GetElementType(); Type sourceType = typeof(T); if(!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } // @@ -213,7 +213,7 @@ namespace System.Collections.ObjectModel // object[] objects = array as object[]; if( objects == null) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } int count = items.Count; @@ -223,7 +223,7 @@ namespace System.Collections.ObjectModel } } catch(ArrayTypeMismatchException) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } } } diff --git a/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs b/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs index 7313d71950..b6fe6ded29 100644 --- a/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs +++ b/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs @@ -53,7 +53,7 @@ namespace System.Collections.ObjectModel /// </summary> new private List<TItem> Items { get { - Contract.Assert(base.Items is List<TItem>); + Debug.Assert(base.Items is List<TItem>); return (List<TItem>)base.Items; } @@ -233,7 +233,7 @@ namespace System.Collections.ObjectModel } private void RemoveKey(TKey key) { - Contract.Assert(key != null, "key shouldn't be null!"); + Debug.Assert(key != null, "key shouldn't be null!"); if (dict != null) { dict.Remove(key); } diff --git a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs index ec7149e4f5..a0b8b3b459 100644 --- a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs +++ b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs @@ -128,7 +128,7 @@ namespace System.Collections.ObjectModel } if (index < 0) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (array.Length - index < Count) { @@ -149,7 +149,7 @@ namespace System.Collections.ObjectModel Type targetType = array.GetType().GetElementType(); Type sourceType = typeof(T); if(!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } // @@ -158,7 +158,7 @@ namespace System.Collections.ObjectModel // object[] objects = array as object[]; if( objects == null) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } int count = list.Count; @@ -168,7 +168,7 @@ namespace System.Collections.ObjectModel } } catch(ArrayTypeMismatchException) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } } } diff --git a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs index 11833c2c1b..5c9e8c44c6 100644 --- a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs +++ b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs @@ -34,7 +34,7 @@ namespace System.Collections.ObjectModel public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary) { if (dictionary == null) { - throw new ArgumentNullException("dictionary"); + throw new ArgumentNullException(nameof(dictionary)); } Contract.EndContractBlock(); m_dictionary = dictionary; @@ -240,7 +240,7 @@ namespace System.Collections.ObjectModel } if (index < 0 || index > array.Length) { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (array.Length - index < Count) { @@ -261,7 +261,7 @@ namespace System.Collections.ObjectModel else { object[] objects = array as object[]; if (objects == null) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } try { @@ -270,7 +270,7 @@ namespace System.Collections.ObjectModel } } catch (ArrayTypeMismatchException) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } } } @@ -596,7 +596,7 @@ namespace System.Collections.ObjectModel Type targetType = array.GetType().GetElementType(); Type sourceType = typeof(T); if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } // @@ -605,7 +605,7 @@ namespace System.Collections.ObjectModel // object[] objects = array as object[]; if (objects == null) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } try { @@ -614,7 +614,7 @@ namespace System.Collections.ObjectModel } } catch (ArrayTypeMismatchException) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType); + ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType(); } } } diff --git a/src/mscorlib/src/System/Collections/SortedList.cs b/src/mscorlib/src/System/Collections/SortedList.cs index 8e3926af01..4a480a2c37 100644 --- a/src/mscorlib/src/System/Collections/SortedList.cs +++ b/src/mscorlib/src/System/Collections/SortedList.cs @@ -60,10 +60,8 @@ namespace System.Collections { // [DebuggerTypeProxy(typeof(System.Collections.SortedList.SortedListDebugView))] [DebuggerDisplay("Count = {Count}")] -[System.Runtime.InteropServices.ComVisible(true)] -#if FEATURE_CORECLR + [System.Runtime.InteropServices.ComVisible(true)] [Obsolete("Non-generic collections have been deprecated. Please use collections in System.Collections.Generic.")] -#endif [Serializable] public class SortedList : IDictionary, ICloneable { @@ -107,7 +105,7 @@ namespace System.Collections { // public SortedList(int initialCapacity) { if (initialCapacity < 0) - throw new ArgumentOutOfRangeException("initialCapacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(initialCapacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); keys = new Object[initialCapacity]; values = new Object[initialCapacity]; @@ -164,7 +162,7 @@ namespace System.Collections { public SortedList(IDictionary d, IComparer comparer) : this(comparer, (d != null ? d.Count : 0)) { if (d==null) - throw new ArgumentNullException("d", Environment.GetResourceString("ArgumentNull_Dictionary")); + throw new ArgumentNullException(nameof(d), Environment.GetResourceString("ArgumentNull_Dictionary")); Contract.EndContractBlock(); d.Keys.CopyTo(keys, 0); d.Values.CopyTo(values, 0); @@ -176,7 +174,7 @@ namespace System.Collections { // ArgumentException is thrown if the key is already present in the sorted list. // public virtual void Add(Object key, Object value) { - if (key == null) throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + if (key == null) throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); Contract.EndContractBlock(); int i = Array.BinarySearch(keys, 0, _size, key, comparer); if (i >= 0) @@ -196,7 +194,7 @@ namespace System.Collections { } set { if (value < Count) { - throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity")); + throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity")); } Contract.EndContractBlock(); @@ -213,7 +211,7 @@ namespace System.Collections { } else { // size can only be zero here. - Contract.Assert( _size == 0, "Size is not zero"); + Debug.Assert( _size == 0, "Size is not zero"); keys = emptyArray; values = emptyArray; } @@ -325,11 +323,11 @@ namespace System.Collections { // Copies the values in this SortedList to an array. public virtual void CopyTo(Array array, int arrayIndex) { if (array == null) - throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Array")); + throw new ArgumentNullException(nameof(array), Environment.GetResourceString("ArgumentNull_Array")); if (array.Rank != 1) throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported")); if (arrayIndex < 0) - throw new ArgumentOutOfRangeException("arrayIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (array.Length - arrayIndex < Count) throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall")); Contract.EndContractBlock(); @@ -368,7 +366,7 @@ namespace System.Collections { // public virtual Object GetByIndex(int index) { if (index < 0 || index >= Count) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); return values[index]; } @@ -394,7 +392,7 @@ namespace System.Collections { // Returns the key of the entry at the given index. // public virtual Object GetKey(int index) { - if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); return keys[index]; } @@ -442,7 +440,7 @@ namespace System.Collections { return null; } set { - if (key == null) throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + if (key == null) throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); Contract.EndContractBlock(); int i = Array.BinarySearch(keys, 0, _size, key, comparer); if (i >= 0) { @@ -463,7 +461,7 @@ namespace System.Collections { // public virtual int IndexOfKey(Object key) { if (key == null) - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); Contract.EndContractBlock(); int ret = Array.BinarySearch(keys, 0, _size, key, comparer); return ret >=0 ? ret : -1; @@ -496,7 +494,7 @@ namespace System.Collections { // decreased by one. // public virtual void RemoveAt(int index) { - if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); _size--; if (index < _size) { @@ -522,7 +520,7 @@ namespace System.Collections { // the given entry is overwritten. // public virtual void SetByIndex(int index, Object value) { - if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); + if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index")); Contract.EndContractBlock(); values[index] = value; version++; @@ -530,10 +528,9 @@ namespace System.Collections { // Returns a thread-safe SortedList. // - [HostProtection(Synchronization=true)] public static SortedList Synchronized(SortedList list) { if (list==null) - throw new ArgumentNullException("list"); + throw new ArgumentNullException(nameof(list)); Contract.EndContractBlock(); return new SyncSortedList(list); } @@ -677,7 +674,7 @@ namespace System.Collections { public override int IndexOfKey(Object key) { if (key == null) - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); Contract.EndContractBlock(); lock(_root) { @@ -888,7 +885,7 @@ namespace System.Collections { public virtual int IndexOf(Object key) { if (key==null) - throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); + throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key")); Contract.EndContractBlock(); int i = Array.BinarySearch(sortedList.keys, 0, @@ -993,7 +990,7 @@ namespace System.Collections { public SortedListDebugView( SortedList sortedList) { if( sortedList == null) { - throw new ArgumentNullException("sortedList"); + throw new ArgumentNullException(nameof(sortedList)); } Contract.EndContractBlock(); diff --git a/src/mscorlib/src/System/Collections/Stack.cs b/src/mscorlib/src/System/Collections/Stack.cs index 0384a4ee81..c3ad15abd8 100644 --- a/src/mscorlib/src/System/Collections/Stack.cs +++ b/src/mscorlib/src/System/Collections/Stack.cs @@ -44,7 +44,7 @@ namespace System.Collections { // must be a non-negative number. public Stack(int initialCapacity) { if (initialCapacity < 0) - throw new ArgumentOutOfRangeException("initialCapacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(initialCapacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); if (initialCapacity < _defaultCapacity) initialCapacity = _defaultCapacity; // Simplify doubling logic in Push. @@ -59,7 +59,7 @@ namespace System.Collections { public Stack(ICollection col) : this((col==null ? 32 : col.Count)) { if (col==null) - throw new ArgumentNullException("col"); + throw new ArgumentNullException(nameof(col)); Contract.EndContractBlock(); IEnumerator en = col.GetEnumerator(); while(en.MoveNext()) @@ -121,11 +121,11 @@ namespace System.Collections { // Copies the stack into an array. public virtual void CopyTo(Array array, int index) { if (array==null) - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); if (array.Rank != 1) throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported")); if (index < 0) - throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (array.Length - index < _size) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); @@ -189,10 +189,9 @@ namespace System.Collections { // Returns a synchronized Stack. // - [HostProtection(Synchronization=true)] public static Stack Synchronized(Stack stack) { if (stack==null) - throw new ArgumentNullException("stack"); + throw new ArgumentNullException(nameof(stack)); Contract.Ensures(Contract.Result<Stack>() != null); Contract.EndContractBlock(); return new SyncStack(stack); @@ -363,7 +362,7 @@ namespace System.Collections { public StackDebugView( Stack stack) { if( stack == null) - throw new ArgumentNullException("stack"); + throw new ArgumentNullException(nameof(stack)); Contract.EndContractBlock(); this.stack = stack; |