SynchronizedCollection.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1.  //------------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.Collections.Generic
  5. {
  6. using System;
  7. using System.Collections;
  8. using System.Diagnostics;
  9. [System.Runtime.InteropServices.ComVisible(false)]
  10. public class SynchronizedCollection<T> : IList<T>, IList
  11. {
  12. List<T> items;
  13. object sync;
  14. public SynchronizedCollection()
  15. {
  16. this.items = new List<T>();
  17. this.sync = new Object();
  18. }
  19. public SynchronizedCollection(object syncRoot)
  20. {
  21. if (syncRoot == null)
  22. throw new ArgumentNullException("syncRoot");
  23. this.items = new List<T>();
  24. this.sync = syncRoot;
  25. }
  26. public SynchronizedCollection(object syncRoot, IEnumerable<T> list)
  27. {
  28. if (syncRoot == null)
  29. throw new ArgumentNullException("syncRoot");
  30. if (list == null)
  31. throw new ArgumentNullException("list");
  32. this.items = new List<T>(list);
  33. this.sync = syncRoot;
  34. }
  35. public SynchronizedCollection(object syncRoot, params T[] list)
  36. {
  37. if (syncRoot == null)
  38. throw new ArgumentNullException("syncRoot");
  39. if (list == null)
  40. throw new ArgumentNullException("list");
  41. this.items = new List<T>(list.Length);
  42. for (int i = 0; i < list.Length; i++)
  43. this.items.Add(list[i]);
  44. this.sync = syncRoot;
  45. }
  46. public int Count { get { lock (this.sync) { return this.items.Count; } } }
  47. protected List<T> Items
  48. {
  49. get { return this.items; }
  50. }
  51. public object SyncRoot
  52. {
  53. get { return this.sync; }
  54. }
  55. public T this[int index]
  56. {
  57. get
  58. {
  59. lock (this.sync)
  60. {
  61. return this.items[index];
  62. }
  63. }
  64. set
  65. {
  66. lock (this.sync)
  67. {
  68. if (index < 0 || index >= this.items.Count)
  69. throw new ArgumentOutOfRangeException("index");
  70. this.SetItem(index, value);
  71. }
  72. }
  73. }
  74. public void Add(T item)
  75. {
  76. lock (this.sync)
  77. {
  78. int index = this.items.Count;
  79. this.InsertItem(index, item);
  80. }
  81. }
  82. public void Clear()
  83. {
  84. lock (this.sync)
  85. {
  86. this.ClearItems();
  87. }
  88. }
  89. public void CopyTo(T[] array, int index)
  90. {
  91. lock (this.sync)
  92. {
  93. this.items.CopyTo(array, index);
  94. }
  95. }
  96. public bool Contains(T item)
  97. {
  98. lock (this.sync)
  99. {
  100. return this.items.Contains(item);
  101. }
  102. }
  103. public IEnumerator<T> GetEnumerator()
  104. {
  105. lock (this.sync)
  106. {
  107. return this.items.GetEnumerator();
  108. }
  109. }
  110. public int IndexOf(T item)
  111. {
  112. lock (this.sync)
  113. {
  114. return this.InternalIndexOf(item);
  115. }
  116. }
  117. public void Insert(int index, T item)
  118. {
  119. lock (this.sync)
  120. {
  121. if (index < 0 || index > this.items.Count)
  122. throw new ArgumentOutOfRangeException("index");
  123. this.InsertItem(index, item);
  124. }
  125. }
  126. int InternalIndexOf(T item)
  127. {
  128. int count = items.Count;
  129. for (int i = 0; i < count; i++)
  130. {
  131. if (object.Equals(items[i], item))
  132. {
  133. return i;
  134. }
  135. }
  136. return -1;
  137. }
  138. public bool Remove(T item)
  139. {
  140. lock (this.sync)
  141. {
  142. int index = this.InternalIndexOf(item);
  143. if (index < 0)
  144. return false;
  145. this.RemoveItem(index);
  146. return true;
  147. }
  148. }
  149. public void RemoveAt(int index)
  150. {
  151. lock (this.sync)
  152. {
  153. if (index < 0 || index >= this.items.Count)
  154. throw new ArgumentOutOfRangeException("index");
  155. this.RemoveItem(index);
  156. }
  157. }
  158. protected virtual void ClearItems()
  159. {
  160. this.items.Clear();
  161. }
  162. protected virtual void InsertItem(int index, T item)
  163. {
  164. this.items.Insert(index, item);
  165. }
  166. protected virtual void RemoveItem(int index)
  167. {
  168. this.items.RemoveAt(index);
  169. }
  170. protected virtual void SetItem(int index, T item)
  171. {
  172. this.items[index] = item;
  173. }
  174. bool ICollection<T>.IsReadOnly
  175. {
  176. get { return false; }
  177. }
  178. IEnumerator IEnumerable.GetEnumerator()
  179. {
  180. return ((IList)this.items).GetEnumerator();
  181. }
  182. bool ICollection.IsSynchronized
  183. {
  184. get { return true; }
  185. }
  186. object ICollection.SyncRoot
  187. {
  188. get { return this.sync; }
  189. }
  190. void ICollection.CopyTo(Array array, int index)
  191. {
  192. lock (this.sync)
  193. {
  194. ((IList)this.items).CopyTo(array, index);
  195. }
  196. }
  197. object IList.this[int index]
  198. {
  199. get
  200. {
  201. return this[index];
  202. }
  203. set
  204. {
  205. VerifyValueType(value);
  206. this[index] = (T)value;
  207. }
  208. }
  209. bool IList.IsReadOnly
  210. {
  211. get { return false; }
  212. }
  213. bool IList.IsFixedSize
  214. {
  215. get { return false; }
  216. }
  217. int IList.Add(object value)
  218. {
  219. VerifyValueType(value);
  220. lock (this.sync)
  221. {
  222. this.Add((T)value);
  223. return this.Count - 1;
  224. }
  225. }
  226. bool IList.Contains(object value)
  227. {
  228. VerifyValueType(value);
  229. return this.Contains((T)value);
  230. }
  231. int IList.IndexOf(object value)
  232. {
  233. VerifyValueType(value);
  234. return this.IndexOf((T)value);
  235. }
  236. void IList.Insert(int index, object value)
  237. {
  238. VerifyValueType(value);
  239. this.Insert(index, (T)value);
  240. }
  241. void IList.Remove(object value)
  242. {
  243. VerifyValueType(value);
  244. this.Remove((T)value);
  245. }
  246. static void VerifyValueType(object value)
  247. {
  248. if (value == null)
  249. {
  250. if (typeof(T).IsValueType)
  251. {
  252. throw new ArgumentException();
  253. }
  254. }
  255. else if (!(value is T))
  256. {
  257. throw new ArgumentException();
  258. }
  259. }
  260. }
  261. }
  262. // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
  263. // Copyright (c) Microsoft Corporation. All rights reserved.