PageRenderTime 74ms CodeModel.GetById 42ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/corlib/System.Collections.ObjectModel/Collection.cs

https://bitbucket.org/danipen/mono
C# | 269 lines | 189 code | 44 blank | 36 comment | 15 complexity | a549326f3c1b3a4ab92f7056d57a7560 MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. // -*- Mode: csharp; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  2. //
  3. // System.Collections.ObjectModel.Collection
  4. //
  5. // Authors:
  6. // Zoltan Varga (vargaz@gmail.com)
  7. // David Waite (mass@akuma.org)
  8. // Marek Safar (marek.safar@gmail.com)
  9. //
  10. // (C) 2005 Novell, Inc.
  11. // (C) 2005 David Waite
  12. //
  13. //
  14. // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
  15. // Copyright (C) 2005 David Waite
  16. // Copyright (C) 2011 Xamarin, Inc (http://www.xamarin.com)
  17. //
  18. // Permission is hereby granted, free of charge, to any person obtaining
  19. // a copy of this software and associated documentation files (the
  20. // "Software"), to deal in the Software without restriction, including
  21. // without limitation the rights to use, copy, modify, merge, publish,
  22. // distribute, sublicense, and/or sell copies of the Software, and to
  23. // permit persons to whom the Software is furnished to do so, subject to
  24. // the following conditions:
  25. //
  26. // The above copyright notice and this permission notice shall be
  27. // included in all copies or substantial portions of the Software.
  28. //
  29. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  30. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  31. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  32. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  33. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  34. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  35. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  36. //
  37. using System;
  38. using System.Collections;
  39. using System.Collections.Generic;
  40. using System.Runtime.InteropServices;
  41. using System.Diagnostics;
  42. namespace System.Collections.ObjectModel
  43. {
  44. [ComVisible (false)]
  45. [Serializable]
  46. [DebuggerDisplay ("Count={Count}")]
  47. [DebuggerTypeProxy (typeof (CollectionDebuggerView<>))]
  48. public class Collection<T> : IList<T>, IList
  49. #if NET_4_5
  50. , IReadOnlyList<T>
  51. #endif
  52. {
  53. IList <T> list;
  54. object syncRoot;
  55. public Collection ()
  56. {
  57. List <T> l = new List <T> ();
  58. IList l2 = l as IList;
  59. syncRoot = l2.SyncRoot;
  60. list = l;
  61. }
  62. public Collection (IList <T> list)
  63. {
  64. if (list == null)
  65. throw new ArgumentNullException ("list");
  66. this.list = list;
  67. ICollection l = list as ICollection;
  68. syncRoot = (l != null) ? l.SyncRoot : new object ();
  69. }
  70. public void Add (T item)
  71. {
  72. int idx = list.Count;
  73. InsertItem (idx, item);
  74. }
  75. public void Clear ()
  76. {
  77. ClearItems ();
  78. }
  79. protected virtual void ClearItems ()
  80. {
  81. list.Clear ();
  82. }
  83. public bool Contains (T item)
  84. {
  85. return list.Contains (item);
  86. }
  87. public void CopyTo (T [] array, int index)
  88. {
  89. list.CopyTo (array, index);
  90. }
  91. public IEnumerator <T> GetEnumerator ()
  92. {
  93. return list.GetEnumerator ();
  94. }
  95. public int IndexOf (T item)
  96. {
  97. return list.IndexOf (item);
  98. }
  99. public void Insert (int index, T item)
  100. {
  101. InsertItem (index, item);
  102. }
  103. protected virtual void InsertItem (int index, T item)
  104. {
  105. list.Insert (index, item);
  106. }
  107. protected IList<T> Items {
  108. get { return list; }
  109. }
  110. public bool Remove (T item)
  111. {
  112. int idx = IndexOf (item);
  113. if (idx == -1)
  114. return false;
  115. RemoveItem (idx);
  116. return true;
  117. }
  118. public void RemoveAt (int index)
  119. {
  120. RemoveItem (index);
  121. }
  122. protected virtual void RemoveItem (int index)
  123. {
  124. list.RemoveAt (index);
  125. }
  126. public int Count {
  127. get { return list.Count; }
  128. }
  129. public T this [int index] {
  130. get { return list [index]; }
  131. set { SetItem (index, value); }
  132. }
  133. bool ICollection<T>.IsReadOnly {
  134. get { return list.IsReadOnly; }
  135. }
  136. protected virtual void SetItem (int index, T item)
  137. {
  138. list[index] = item;
  139. }
  140. #region Helper methods for non-generic interfaces
  141. internal static T ConvertItem (object item)
  142. {
  143. if (CollectionHelpers.IsValidItem<T> (item))
  144. return (T)item;
  145. throw new ArgumentException ("item");
  146. }
  147. internal static void CheckWritable (IList <T> list)
  148. {
  149. if (list.IsReadOnly)
  150. throw new NotSupportedException ();
  151. }
  152. internal static bool IsSynchronized (IList <T> list)
  153. {
  154. ICollection c = list as ICollection;
  155. return (c != null) ? c.IsSynchronized : false;
  156. }
  157. internal static bool IsFixedSize (IList <T> list)
  158. {
  159. IList l = list as IList;
  160. return (l != null) ? l.IsFixedSize : false;
  161. }
  162. #endregion
  163. #region Not generic interface implementations
  164. void ICollection.CopyTo (Array array, int index)
  165. {
  166. ((ICollection)list).CopyTo (array, index);
  167. }
  168. IEnumerator IEnumerable.GetEnumerator ()
  169. {
  170. return (IEnumerator) list.GetEnumerator ();
  171. }
  172. int IList.Add (object value)
  173. {
  174. int idx = list.Count;
  175. InsertItem (idx, ConvertItem (value));
  176. return idx;
  177. }
  178. bool IList.Contains (object value)
  179. {
  180. if (CollectionHelpers.IsValidItem<T> (value))
  181. return list.Contains ((T) value);
  182. return false;
  183. }
  184. int IList.IndexOf (object value)
  185. {
  186. if (CollectionHelpers.IsValidItem<T> (value))
  187. return list.IndexOf ((T) value);
  188. return -1;
  189. }
  190. void IList.Insert (int index, object value)
  191. {
  192. InsertItem (index, ConvertItem (value));
  193. }
  194. void IList.Remove (object value)
  195. {
  196. CheckWritable (list);
  197. int idx = IndexOf (ConvertItem (value));
  198. RemoveItem (idx);
  199. }
  200. bool ICollection.IsSynchronized {
  201. get { return IsSynchronized (list); }
  202. }
  203. object ICollection.SyncRoot {
  204. get { return syncRoot; }
  205. }
  206. bool IList.IsFixedSize {
  207. get { return IsFixedSize (list); }
  208. }
  209. bool IList.IsReadOnly {
  210. get { return list.IsReadOnly; }
  211. }
  212. object IList.this [int index] {
  213. get { return list [index]; }
  214. set { SetItem (index, ConvertItem (value)); }
  215. }
  216. #endregion
  217. }
  218. static class CollectionHelpers
  219. {
  220. public static bool IsValidItem<T> (object item)
  221. {
  222. return item is T || (item == null && ! typeof (T).IsValueType);
  223. }
  224. }
  225. }