0
|
1 using System;
|
|
2 using System.Collections;
|
|
3 using System.Collections.Generic;
|
|
4 using System.ComponentModel;
|
|
5 using System.Diagnostics;
|
|
6
|
|
7 namespace BLToolkit.EditableObjects
|
|
8 {
|
|
9 [Serializable]
|
|
10 [DebuggerDisplay("Count = {Count}")]
|
|
11 public class EditableList<T> : EditableArrayList, IList<T>
|
|
12 {
|
|
13 #region Constructors
|
|
14
|
|
15 public EditableList()
|
|
16 : base(typeof(T))
|
|
17 {
|
|
18 }
|
|
19
|
|
20 public EditableList(int capacity)
|
|
21 : base(typeof(T), capacity)
|
|
22 {
|
|
23 }
|
|
24
|
|
25 public EditableList(ICollection c)
|
|
26 : base(typeof(T), c)
|
|
27 {
|
|
28 }
|
|
29
|
|
30 public EditableList(bool trackChanges)
|
|
31 : base(typeof(T), trackChanges)
|
|
32 {
|
|
33 }
|
|
34
|
|
35 public EditableList(int capacity, bool trackChanges)
|
|
36 : base(typeof(T), capacity, trackChanges)
|
|
37 {
|
|
38 }
|
|
39
|
|
40 public EditableList(ICollection c, bool trackChanges)
|
|
41 : base(typeof(T), c, trackChanges)
|
|
42 {
|
|
43 }
|
|
44
|
|
45 public EditableList(EditableList<T> list)
|
|
46 : base(list, true)
|
|
47 {
|
|
48 }
|
|
49
|
|
50 public EditableList(EditableList<T> list, bool trackChanges)
|
|
51 : base(list, trackChanges)
|
|
52 {
|
|
53 }
|
|
54
|
|
55 #endregion
|
|
56
|
|
57 #region Typed Methods
|
|
58
|
|
59 public override object Clone()
|
|
60 {
|
|
61 return Clone(new EditableList<T>((ArrayList)List.Clone()));
|
|
62 }
|
|
63
|
|
64 public new T this[int index]
|
|
65 {
|
|
66 get { return (T)base[index]; }
|
|
67 set { base[index] = value; }
|
|
68 }
|
|
69
|
|
70 public new T[] ToArray()
|
|
71 {
|
|
72 return (T[])base.ToArray(typeof(T));
|
|
73 }
|
|
74
|
|
75 public new T AddNew()
|
|
76 {
|
|
77 return (T)base.AddNew();
|
|
78 }
|
|
79
|
|
80 public int RemoveAll(Predicate<T> match)
|
|
81 {
|
|
82 var n = 0;
|
|
83
|
|
84 for (var i = 0; i < Count; i++)
|
|
85 {
|
|
86 var item = this[i];
|
|
87
|
|
88 if (match(item))
|
|
89 {
|
|
90 Remove((object)item);
|
|
91 i--;
|
|
92 n++;
|
|
93 }
|
|
94 }
|
|
95
|
|
96 return n;
|
|
97 }
|
|
98
|
|
99 #endregion
|
|
100
|
|
101 #region Like List<T> Methods
|
|
102
|
|
103 public T Find(Predicate<T> match)
|
|
104 {
|
|
105 if (match == null) throw new ArgumentNullException("match");
|
|
106
|
|
107 foreach (T t in List)
|
|
108 if (match(t))
|
|
109 return t;
|
|
110
|
|
111 return default(T);
|
|
112 }
|
|
113
|
|
114 public EditableList<T> FindAll(Predicate<T> match)
|
|
115 {
|
|
116 if (match == null) throw new ArgumentNullException("match");
|
|
117
|
|
118 var list = new EditableList<T>();
|
|
119
|
|
120 foreach (T t in List)
|
|
121 if (match(t))
|
|
122 list.Add(t);
|
|
123
|
|
124 return list;
|
|
125 }
|
|
126
|
|
127 public int FindIndex(Predicate<T> match)
|
|
128 {
|
|
129 return FindIndex(0, List.Count, match);
|
|
130 }
|
|
131
|
|
132 public int FindIndex(int startIndex, Predicate<T> match)
|
|
133 {
|
|
134 return FindIndex(startIndex, List.Count - startIndex, match);
|
|
135 }
|
|
136
|
|
137 public int FindIndex(int startIndex, int count, Predicate<T> match)
|
|
138 {
|
|
139 if (startIndex > List.Count)
|
|
140 throw new ArgumentOutOfRangeException("startIndex");
|
|
141
|
|
142 if (count < 0 || startIndex > List.Count - count)
|
|
143 throw new ArgumentOutOfRangeException("count");
|
|
144
|
|
145 if (match == null)
|
|
146 throw new ArgumentNullException("match");
|
|
147
|
|
148 for (var i = startIndex; i < startIndex + count; i++)
|
|
149 if (match((T)List[i]))
|
|
150 return i;
|
|
151
|
|
152 return -1;
|
|
153 }
|
|
154
|
|
155 public T FindLast(Predicate<T> match)
|
|
156 {
|
|
157 if (match == null) throw new ArgumentNullException("match");
|
|
158
|
|
159 for (var i = List.Count - 1; i >= 0; i--)
|
|
160 {
|
|
161 var t = (T)List[i];
|
|
162
|
|
163 if (match(t))
|
|
164 return t;
|
|
165 }
|
|
166
|
|
167 return default(T);
|
|
168 }
|
|
169
|
|
170 public int FindLastIndex(Predicate<T> match)
|
|
171 {
|
|
172 return FindLastIndex(List.Count - 1, List.Count, match);
|
|
173 }
|
|
174
|
|
175 public int FindLastIndex(int startIndex, Predicate<T> match)
|
|
176 {
|
|
177 return FindLastIndex(startIndex, startIndex + 1, match);
|
|
178 }
|
|
179
|
|
180 public int FindLastIndex(int startIndex, int count, Predicate<T> match)
|
|
181 {
|
|
182 if (startIndex >= List.Count)
|
|
183 throw new ArgumentOutOfRangeException("startIndex");
|
|
184
|
|
185 if (count < 0 || startIndex - count + 1 < 0)
|
|
186 throw new ArgumentOutOfRangeException("count");
|
|
187
|
|
188 if (match == null)
|
|
189 throw new ArgumentNullException("match");
|
|
190
|
|
191 for (var i = startIndex; i > startIndex - count; i--)
|
|
192 {
|
|
193 var t = (T)List[i];
|
|
194
|
|
195 if (match(t))
|
|
196 return i;
|
|
197 }
|
|
198
|
|
199 return -1;
|
|
200 }
|
|
201
|
|
202 public void ForEach(Action<T> action)
|
|
203 {
|
|
204 if (action == null) throw new ArgumentNullException("action");
|
|
205
|
|
206 foreach (T t in List)
|
|
207 action(t);
|
|
208 }
|
|
209
|
|
210 public void Sort(IComparer<T> comparer)
|
|
211 {
|
|
212 Sort(0, List.Count, comparer);
|
|
213 }
|
|
214
|
|
215 public void Sort(int index, int count, IComparer<T> comparer)
|
|
216 {
|
|
217 if (List.Count > 1 && count > 1)
|
|
218 {
|
|
219 var items = new T[count];
|
|
220
|
|
221 List.CopyTo(index, items, 0, count);
|
|
222 Array.Sort(items, index, count, comparer);
|
|
223
|
|
224 for (var i = 0; i < count; i++)
|
|
225 List[i + index] = items[i];
|
|
226
|
|
227 OnListChanged(ListChangedType.Reset, 0);
|
|
228 }
|
|
229 }
|
|
230
|
|
231 public void Sort(Comparison<T> comparison)
|
|
232 {
|
|
233 if (List.Count > 1)
|
|
234 {
|
|
235 var items = new T[List.Count];
|
|
236
|
|
237 List.CopyTo(items);
|
|
238 Array.Sort(items, comparison);
|
|
239
|
|
240 for (var i = 0; i < List.Count; i++)
|
|
241 List[i] = items[i];
|
|
242
|
|
243 OnListChanged(ListChangedType.Reset, 0);
|
|
244 }
|
|
245 }
|
|
246
|
|
247 #endregion
|
|
248
|
|
249 #region Static Methods
|
|
250
|
|
251 internal EditableList(ArrayList list)
|
|
252 : base(typeof(T), list)
|
|
253 {
|
|
254 }
|
|
255
|
|
256 public static EditableList<T> Adapter(List<T> list)
|
|
257 {
|
|
258 return new EditableList<T>(ArrayList.Adapter(list));
|
|
259 }
|
|
260
|
|
261 public static new EditableList<T> Adapter(IList list)
|
|
262 {
|
|
263 return list is ArrayList?
|
|
264 new EditableList<T>((ArrayList)list):
|
|
265 new EditableList<T>(ArrayList.Adapter(list));
|
|
266 }
|
|
267
|
|
268 #endregion
|
|
269
|
|
270 #region IList<T> Members
|
|
271
|
|
272 public int IndexOf(T item)
|
|
273 {
|
|
274 return IndexOf((object)item);
|
|
275 }
|
|
276
|
|
277 public void Insert(int index, T item)
|
|
278 {
|
|
279 Insert(index, (object)item);
|
|
280 }
|
|
281
|
|
282 #endregion
|
|
283
|
|
284 #region ICollection<T> Members
|
|
285
|
|
286 public void Add(T item)
|
|
287 {
|
|
288 Add((object)item);
|
|
289 }
|
|
290
|
|
291 public bool Contains(T item)
|
|
292 {
|
|
293 return Contains((object)item);
|
|
294 }
|
|
295
|
|
296 public void CopyTo(T[] array, int arrayIndex)
|
|
297 {
|
|
298 CopyTo((Array)array, arrayIndex);
|
|
299 }
|
|
300
|
|
301 public bool Remove(T item)
|
|
302 {
|
|
303 if (Contains(item) == false)
|
|
304 return false;
|
|
305
|
|
306 Remove((object)item);
|
|
307
|
|
308 return true;
|
|
309 }
|
|
310
|
|
311 #endregion
|
|
312
|
|
313 #region IEnumerable<T> Members
|
|
314
|
|
315 public new IEnumerator<T> GetEnumerator()
|
|
316 {
|
|
317 return new Enumerator(List.GetEnumerator());
|
|
318 }
|
|
319
|
|
320 class Enumerator : IEnumerator<T>
|
|
321 {
|
|
322 public Enumerator(IEnumerator enumerator)
|
|
323 {
|
|
324 _enumerator = enumerator;
|
|
325 }
|
|
326
|
|
327 private readonly IEnumerator _enumerator;
|
|
328
|
|
329 #region IEnumerator<T> Members
|
|
330
|
|
331 T IEnumerator<T>.Current
|
|
332 {
|
|
333 get { return (T)_enumerator.Current; }
|
|
334 }
|
|
335
|
|
336 #endregion
|
|
337
|
|
338 #region IEnumerator Members
|
|
339
|
|
340 object IEnumerator.Current
|
|
341 {
|
|
342 get { return _enumerator.Current; }
|
|
343 }
|
|
344
|
|
345 bool IEnumerator.MoveNext()
|
|
346 {
|
|
347 return _enumerator.MoveNext();
|
|
348 }
|
|
349
|
|
350 void IEnumerator.Reset()
|
|
351 {
|
|
352 _enumerator.Reset();
|
|
353 }
|
|
354
|
|
355 #endregion
|
|
356
|
|
357 #region IDisposable Members
|
|
358
|
|
359 void IDisposable.Dispose()
|
|
360 {
|
|
361 }
|
|
362
|
|
363 #endregion
|
|
364 }
|
|
365
|
|
366 #endregion
|
|
367 }
|
|
368 }
|
|
369
|