summaryrefslogtreecommitdiff
path: root/src/mscorlib/shared/System/Collections/ObjectModel/ReadOnlyCollection.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/shared/System/Collections/ObjectModel/ReadOnlyCollection.cs')
-rw-r--r--src/mscorlib/shared/System/Collections/ObjectModel/ReadOnlyCollection.cs279
1 files changed, 279 insertions, 0 deletions
diff --git a/src/mscorlib/shared/System/Collections/ObjectModel/ReadOnlyCollection.cs b/src/mscorlib/shared/System/Collections/ObjectModel/ReadOnlyCollection.cs
new file mode 100644
index 0000000000..f1d2a0969b
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/ObjectModel/ReadOnlyCollection.cs
@@ -0,0 +1,279 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace System.Collections.ObjectModel
+{
+ [Serializable]
+ [DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
+ [DebuggerDisplay("Count = {Count}")]
+ [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
+ public class ReadOnlyCollection<T> : IList<T>, IList, IReadOnlyList<T>
+ {
+ private IList<T> list; // Do not rename (binary serialization)
+ [NonSerialized]
+ private Object _syncRoot;
+
+ public ReadOnlyCollection(IList<T> list)
+ {
+ if (list == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.list);
+ }
+ this.list = list;
+ }
+
+ public int Count
+ {
+ get { return list.Count; }
+ }
+
+ public T this[int index]
+ {
+ get { return list[index]; }
+ }
+
+ public bool Contains(T value)
+ {
+ return list.Contains(value);
+ }
+
+ public void CopyTo(T[] array, int index)
+ {
+ list.CopyTo(array, index);
+ }
+
+ public IEnumerator<T> GetEnumerator()
+ {
+ return list.GetEnumerator();
+ }
+
+ public int IndexOf(T value)
+ {
+ return list.IndexOf(value);
+ }
+
+ protected IList<T> Items
+ {
+ get
+ {
+ return list;
+ }
+ }
+
+ bool ICollection<T>.IsReadOnly
+ {
+ get { return true; }
+ }
+
+ T IList<T>.this[int index]
+ {
+ get { return list[index]; }
+ set
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ }
+ }
+
+ void ICollection<T>.Add(T value)
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ }
+
+ void ICollection<T>.Clear()
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ }
+
+ void IList<T>.Insert(int index, T value)
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ }
+
+ bool ICollection<T>.Remove(T value)
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ return false;
+ }
+
+ void IList<T>.RemoveAt(int index)
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)list).GetEnumerator();
+ }
+
+ bool ICollection.IsSynchronized
+ {
+ get { return false; }
+ }
+
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
+ ICollection c = list as ICollection;
+ if (c != null)
+ {
+ _syncRoot = c.SyncRoot;
+ }
+ else
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ }
+ }
+ return _syncRoot;
+ }
+ }
+
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ }
+
+ if (array.Rank != 1)
+ {
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
+ }
+
+ if (array.GetLowerBound(0) != 0)
+ {
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
+ }
+
+ if (index < 0)
+ {
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
+ }
+
+ if (array.Length - index < Count)
+ {
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
+ }
+
+ T[] items = array as T[];
+ if (items != null)
+ {
+ list.CopyTo(items, index);
+ }
+ else
+ {
+ //
+ // Catch the obvious case assignment will fail.
+ // We can't find all possible problems by doing the check though.
+ // For example, if the element type of the Array is derived from T,
+ // we can't figure out if we can successfully copy the element beforehand.
+ //
+ Type targetType = array.GetType().GetElementType();
+ Type sourceType = typeof(T);
+ if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType)))
+ {
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
+ }
+
+ //
+ // We can't cast array of value type to object[], so we don't support
+ // widening of primitive types here.
+ //
+ object[] objects = array as object[];
+ if (objects == null)
+ {
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
+ }
+
+ int count = list.Count;
+ try
+ {
+ for (int i = 0; i < count; i++)
+ {
+ objects[index++] = list[i];
+ }
+ }
+ catch (ArrayTypeMismatchException)
+ {
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
+ }
+ }
+ }
+
+ bool IList.IsFixedSize
+ {
+ get { return true; }
+ }
+
+ bool IList.IsReadOnly
+ {
+ get { return true; }
+ }
+
+ object IList.this[int index]
+ {
+ get { return list[index]; }
+ set
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ }
+ }
+
+ int IList.Add(object value)
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ return -1;
+ }
+
+ void IList.Clear()
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ }
+
+ private static bool IsCompatibleObject(object value)
+ {
+ // Non-null values are fine. Only accept nulls if T is a class or Nullable<U>.
+ // Note that default(T) is not equal to null for value types except when T is Nullable<U>.
+ return ((value is T) || (value == null && default(T) == null));
+ }
+
+ bool IList.Contains(object value)
+ {
+ if (IsCompatibleObject(value))
+ {
+ return Contains((T)value);
+ }
+ return false;
+ }
+
+ int IList.IndexOf(object value)
+ {
+ if (IsCompatibleObject(value))
+ {
+ return IndexOf((T)value);
+ }
+ return -1;
+ }
+
+ void IList.Insert(int index, object value)
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ }
+
+ void IList.Remove(object value)
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ }
+
+ void IList.RemoveAt(int index)
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ }
+ }
+}