1 // -*- Mode: csharp; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3 // System.Collections.ObjectModel.Collection
6 // Zoltan Varga (vargaz@gmail.com)
7 // David Waite (mass@akuma.org)
8 // Marek Safar (marek.safar@gmail.com)
10 // (C) 2005 Novell, Inc.
11 // (C) 2005 David Waite
15 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
16 // Copyright (C) 2005 David Waite
17 // Copyright (C) 2011 Xamarin, Inc (http://www.xamarin.com)
19 // Permission is hereby granted, free of charge, to any person obtaining
20 // a copy of this software and associated documentation files (the
21 // "Software"), to deal in the Software without restriction, including
22 // without limitation the rights to use, copy, modify, merge, publish,
23 // distribute, sublicense, and/or sell copies of the Software, and to
24 // permit persons to whom the Software is furnished to do so, subject to
25 // the following conditions:
27 // The above copyright notice and this permission notice shall be
28 // included in all copies or substantial portions of the Software.
30 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
34 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 using System.Collections;
41 using System.Collections.Generic;
42 using System.Runtime.InteropServices;
43 using System.Diagnostics;
45 namespace System.Collections.ObjectModel
49 [DebuggerDisplay ("Count={Count}")]
50 [DebuggerTypeProxy (typeof (CollectionDebuggerView<>))]
51 public class Collection<T> : IList<T>, IList
57 [field:NonSerializedAttribute()]
62 List <T> l = new List <T> ();
63 IList l2 = l as IList;
64 syncRoot = l2.SyncRoot;
68 public Collection (IList <T> items)
71 throw new ArgumentNullException ("items");
73 ICollection l = items as ICollection;
74 syncRoot = (l != null) ? l.SyncRoot : new object ();
77 public void Add (T item)
79 int idx = items.Count;
80 InsertItem (idx, item);
88 protected virtual void ClearItems ()
93 public bool Contains (T item)
95 return items.Contains (item);
98 public void CopyTo (T [] array, int index)
100 items.CopyTo (array, index);
103 public IEnumerator <T> GetEnumerator ()
105 return items.GetEnumerator ();
108 public int IndexOf (T item)
110 return items.IndexOf (item);
113 public void Insert (int index, T item)
115 InsertItem (index, item);
118 protected virtual void InsertItem (int index, T item)
120 items.Insert (index, item);
123 protected IList<T> Items {
124 get { return items; }
127 public bool Remove (T item)
129 int idx = IndexOf (item);
138 public void RemoveAt (int index)
143 protected virtual void RemoveItem (int index)
145 items.RemoveAt (index);
149 get { return items.Count; }
152 public T this [int index] {
153 get { return items [index]; }
154 set { SetItem (index, value); }
157 bool ICollection<T>.IsReadOnly {
158 get { return items.IsReadOnly; }
161 protected virtual void SetItem (int index, T item)
167 #region Helper methods for non-generic interfaces
169 internal static T ConvertItem (object item)
171 if (CollectionHelpers.IsValidItem<T> (item))
173 throw new ArgumentException ("item");
176 internal static void CheckWritable (IList <T> items)
178 if (items.IsReadOnly)
179 throw new NotSupportedException ();
182 internal static bool IsSynchronized (IList <T> items)
184 ICollection c = items as ICollection;
185 return (c != null) ? c.IsSynchronized : false;
188 internal static bool IsFixedSize (IList <T> items)
190 IList l = items as IList;
191 return (l != null) ? l.IsFixedSize : false;
195 #region Not generic interface implementations
196 void ICollection.CopyTo (Array array, int index)
198 ((ICollection)items).CopyTo (array, index);
201 IEnumerator IEnumerable.GetEnumerator ()
203 return (IEnumerator) items.GetEnumerator ();
206 int IList.Add (object value)
208 int idx = items.Count;
209 InsertItem (idx, ConvertItem (value));
213 bool IList.Contains (object value)
215 if (CollectionHelpers.IsValidItem<T> (value))
216 return items.Contains ((T) value);
220 int IList.IndexOf (object value)
222 if (CollectionHelpers.IsValidItem<T> (value))
223 return items.IndexOf ((T) value);
227 void IList.Insert (int index, object value)
229 InsertItem (index, ConvertItem (value));
232 void IList.Remove (object value)
234 CheckWritable (items);
236 int idx = IndexOf (ConvertItem (value));
241 bool ICollection.IsSynchronized {
242 get { return IsSynchronized (items); }
245 object ICollection.SyncRoot {
246 get { return syncRoot; }
248 bool IList.IsFixedSize {
249 get { return IsFixedSize (items); }
252 bool IList.IsReadOnly {
253 get { return items.IsReadOnly; }
256 object IList.this [int index] {
257 get { return items [index]; }
258 set { SetItem (index, ConvertItem (value)); }
263 static class CollectionHelpers
265 public static bool IsValidItem<T> (object item)
267 return item is T || (item == null && ! typeof (T).IsValueType);