[Serializable]
public class List<T> : IList<T>, System.Collections.IList, IReadOnlyList<T>
{
public ReadOnlyCollection<T> AsReadOnly()
{
Contract.Ensures(Contract.Result<ReadOnlyCollection<T>>() != null);
return new ReadOnlyCollection<T>(this);
}
}
public abstract class Array : ICloneable, IList, IStructuralComparable, IStructuralEquatable
{
public static ReadOnlyCollection<T> AsReadOnly<T>(T[] array)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
Contract.Ensures(Contract.Result<ReadOnlyCollection<T>>() != null);
// T[] implements IList<T>.
return new ReadOnlyCollection<T>(array);
}
}
[Serializable]
public class ReadOnlyCollection<T> : IList<T>, IList, IReadOnlyList<T>
{
IList<T> list;
[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.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
if (array.Length - index < Count)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
T[] items = array as T[];
if (items != null)
{
list.CopyTo(items, index);
}
else
{
Type targetType = array.GetType().GetElementType();
Type sourceType = typeof(T);
if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType)))
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
}
object[] objects = array as object[];
if (objects == null)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
}
int count = list.Count;
try
{
for (int i = 0; i < count; i++)
{
objects[index++] = list[i];
}
}
catch (ArrayTypeMismatchException)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.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)
{
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);
}
}
[Serializable]
public abstract class ReadOnlyCollectionBase : ICollection
{
ArrayList list;
protected ArrayList InnerList
{
get
{
if (list == null)
list = new ArrayList();
return list;
}
}
public virtual int Count
{
get { return InnerList.Count; }
}
bool ICollection.IsSynchronized
{
get { return InnerList.IsSynchronized; }
}
object ICollection.SyncRoot
{
get { return InnerList.SyncRoot; }
}
void ICollection.CopyTo(Array array, int index)
{
InnerList.CopyTo(array, index);
}
public virtual IEnumerator GetEnumerator()
{
return InnerList.GetEnumerator();
}
}