The Labs \ Source Viewer \ SSCLI \ System.Collections.ObjectModel \ ReadOnlyCollection

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace System.Collections.ObjectModel
  16. {
  17.     using System;
  18.     using System.Collections;
  19.     using System.Collections.Generic;
  20.     using System.Diagnostics;
  21.    
  22.     [Serializable()]
  23.     [System.Runtime.InteropServices.ComVisible(false)]
  24.     [DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
  25.     [DebuggerDisplay("Count = {Count}")]
  26.     public class ReadOnlyCollection<T> : IList<T>, IList
  27.     {
  28.         IList<T> list;
  29.         [NonSerialized()]
  30.         private object _syncRoot;
  31.        
  32.         public ReadOnlyCollection(IList<T> list)
  33.         {
  34.             if (list == null) {
  35.                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.list);
  36.             }
  37.             this.list = list;
  38.         }
  39.        
  40.         public int Count {
  41.             get { return list.Count; }
  42.         }
  43.        
  44.         public T this[int index]
  45.         {
  46.             get { return list[index]; }
  47.         }
  48.        
  49.         public bool Contains(T value)
  50.         {
  51.             return list.Contains(value);
  52.         }
  53.        
  54.         public void CopyTo(T[] array, int index)
  55.         {
  56.             list.CopyTo(array, index);
  57.         }
  58.        
  59.         public IEnumerator<T> GetEnumerator()
  60.         {
  61.             return list.GetEnumerator();
  62.         }
  63.        
  64.         public int IndexOf(T value)
  65.         {
  66.             return list.IndexOf(value);
  67.         }
  68.        
  69.         protected IList<T> Items {
  70.             get { return list; }
  71.         }
  72.        
  73.         bool ICollection<T>.IsReadOnly {
  74.             get { return true; }
  75.         }
  76.        
  77.         T IList<T>.this[int index]
  78.         {
  79.             get { return list[index]; }
  80.             set { ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection); }
  81.         }
  82.        
  83.         void ICollection<T>.Add(T value)
  84.         {
  85.             ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
  86.         }
  87.        
  88.         void ICollection<T>.Clear()
  89.         {
  90.             ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
  91.         }
  92.        
  93.         void IList<T>.Insert(int index, T value)
  94.         {
  95.             ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
  96.         }
  97.        
  98.         bool ICollection<T>.Remove(T value)
  99.         {
  100.             ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
  101.             return false;
  102.         }
  103.        
  104.         void IList<T>.RemoveAt(int index)
  105.         {
  106.             ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
  107.         }
  108.        
  109.         IEnumerator IEnumerable.GetEnumerator()
  110.         {
  111.             return ((IEnumerable)list).GetEnumerator();
  112.         }
  113.        
  114.         bool ICollection.IsSynchronized {
  115.             get { return false; }
  116.         }
  117.        
  118.         object ICollection.SyncRoot {
  119.             get {
  120.                 if (_syncRoot == null) {
  121.                     ICollection c = list as ICollection;
  122.                     if (c != null) {
  123.                         _syncRoot = c.SyncRoot;
  124.                     }
  125.                     else {
  126.                         System.Threading.Interlocked.CompareExchange(ref _syncRoot, new object(), null);
  127.                     }
  128.                 }
  129.                 return _syncRoot;
  130.             }
  131.         }
  132.        
  133.         void ICollection.CopyTo(Array array, int index)
  134.         {
  135.             if (array == null) {
  136.                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
  137.             }
  138.            
  139.             if (array.Rank != 1) {
  140.                 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
  141.             }
  142.            
  143.             if (array.GetLowerBound(0) != 0) {
  144.                 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
  145.             }
  146.            
  147.             if (index < 0) {
  148.                 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
  149.             }
  150.            
  151.             if (array.Length - index < Count) {
  152.                 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
  153.             }
  154.            
  155.             T[] items = array as T[];
  156.             if (items != null) {
  157.                 list.CopyTo(items, index);
  158.             }
  159.             else {
  160.                 //
  161.                 // Catch the obvious case assignment will fail.
  162.                 // We can found all possible problems by doing the check though.
  163.                 // For example, if the element type of the Array is derived from T,
  164.                 // we can't figure out if we can successfully copy the element beforehand.
  165.                 //
  166.                 Type targetType = array.GetType().GetElementType();
  167.                 Type sourceType = typeof(T);
  168.                 if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) {
  169.                     ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
  170.                 }
  171.                
  172.                 //
  173.                 // We can't cast array of value type to object[], so we don't support
  174.                 // widening of primitive types here.
  175.                 //
  176.                 object[] objects = array as object[];
  177.                 if (objects == null) {
  178.                     ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
  179.                 }
  180.                
  181.                 int count = list.Count;
  182.                 try {
  183.                     for (int i = 0; i < count; i++) {
  184.                         objects[index++] = list[i];
  185.                     }
  186.                 }
  187.                 catch (ArrayTypeMismatchException) {
  188.                     ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
  189.                 }
  190.             }
  191.         }
  192.        
  193.         bool IList.IsFixedSize {
  194.             get { return true; }
  195.         }
  196.        
  197.         bool IList.IsReadOnly {
  198.             get { return true; }
  199.         }
  200.        
  201.         object IList.this[int index]
  202.         {
  203.             get { return list[index]; }
  204.             set { ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection); }
  205.         }
  206.        
  207.         int IList.Add(object value)
  208.         {
  209.             ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
  210.             return -1;
  211.         }
  212.        
  213.         void IList.Clear()
  214.         {
  215.             ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
  216.         }
  217.        
  218.         private static bool IsCompatibleObject(object value)
  219.         {
  220.             if ((value is T) || (value == null && !typeof(T).IsValueType)) {
  221.                 return true;
  222.             }
  223.             return false;
  224.         }
  225.        
  226.         bool IList.Contains(object value)
  227.         {
  228.             if (IsCompatibleObject(value)) {
  229.                 return Contains((T)value);
  230.             }
  231.             return false;
  232.         }
  233.        
  234.         int IList.IndexOf(object value)
  235.         {
  236.             if (IsCompatibleObject(value)) {
  237.                 return IndexOf((T)value);
  238.             }
  239.             return -1;
  240.         }
  241.        
  242.         void IList.Insert(int index, object value)
  243.         {
  244.             ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
  245.         }
  246.        
  247.         void IList.Remove(object value)
  248.         {
  249.             ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
  250.         }
  251.        
  252.         void IList.RemoveAt(int index)
  253.         {
  254.             ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
  255.         }
  256.        
  257.         private static void VerifyValueType(object value)
  258.         {
  259.             if (!IsCompatibleObject(value)) {
  260.                 ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
  261.             }
  262.         }
  263.     }
  264. }

Developer Fusion