Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/Netron.Diagramming.Core-3.0.2672.12446/Collections/CollectionBase.cs @ 4068

Last change on this file since 4068 was 4068, checked in by swagner, 14 years ago

Sorted usings and removed unused usings in entire solution (#1094)

File size: 21.5 KB
Line 
1
2using System;
3using System.Collections;
4using System.Collections.Generic;
5using System.Diagnostics;
6using System.IO;
7using System.Runtime.Serialization.Formatters.Binary;
8using Netron.NetronLight;
9namespace Netron.Diagramming.Core {
10  /// <summary>
11  /// CollectionBase is a base class that can be used to more easily implement the
12  /// generic ICollection&lt;T&gt; and non-generic ICollection interfaces.
13  /// </summary>
14  /// <remarks>
15  /// <para>To use CollectionBase as a base class, the derived class must override
16  /// the Count, GetEnumerator, Add, Clear, and Remove methods. </para>
17  /// <para>ICollection&lt;T&gt;.Contains need not be implemented by the
18  /// derived class, but it should be strongly considered, because the CollectionBase implementation
19  /// may not be very efficient.</para>
20  /// </remarks>
21  /// <typeparam name="T">The item type of the collection.</typeparam>
22
23  [DebuggerDisplay("{DebuggerDisplayString()}")]
24  public partial class CollectionBase<T> : ICollection<T>, ICollection, IList<T>, ICollectionBase<T>, IShowable {
25    #region Events
26    /// <summary>
27    /// Occurs when an item is added to the collection.
28    /// </summary>
29    public event EventHandler<CollectionEventArgs<T>> OnItemAdded;
30    /// <summary>
31    /// Occurs when an item is removed from the collection.
32    /// </summary>
33    public event EventHandler<CollectionEventArgs<T>> OnItemRemoved;
34    /// <summary>
35    /// Occurs when the collection is cleared.
36    /// </summary>
37    public event EventHandler OnClear;
38    #endregion
39
40    #region Fields
41    /// <summary>
42    /// the internal generic list on which this collection is based
43    /// </summary>                                                                   
44    protected List<T> innerList;
45    /// <summary>
46    /// whether this collection is readonly
47    /// </summary>
48    bool mReadOnly = false;
49    #endregion
50
51    #region Properties
52    /// <summary>
53    /// Indicates whether the collection is read-only.
54    /// </summary>
55    bool ICollection<T>.IsReadOnly {
56      get {
57        return mReadOnly;
58      }
59    }
60
61    /// <summary>
62    /// Gets a value indicating whether this instance is empty.
63    /// </summary>
64    /// <value><c>true</c> if this instance is empty; otherwise, <c>false</c>.</value>
65    public virtual bool IsEmpty {
66      get { return this.innerList.Count == 0; }
67    }
68    #endregion
69
70
71
72    #region Constructor
73
74    /// <summary>
75    /// Creates a new CollectionBase.
76    /// </summary>
77    public CollectionBase() {
78      innerList = new List<T>();
79    }
80
81    /// <summary>
82    /// Initializes a new instance of the <see cref="T:CollectionBase&lt;T&gt;"/> class.
83    /// </summary>
84    /// <param name="baseCollection">The base collection.</param>
85    public CollectionBase(ICollectionBase<T> baseCollection)
86      : this() {
87      innerList.AddRange(baseCollection);
88    }
89
90    /// <summary>
91    /// Initializes a new instance of the <see cref="T:CollectionBase&lt;T&gt;"/> class.
92    /// </summary>
93    /// <param name="baseCollection">The base collection.</param>
94    /// <param name="readOnly">if set to <c>true</c> [read only].</param>
95    public CollectionBase(ICollectionBase<T> baseCollection, bool readOnly)
96      : this() {
97      mReadOnly = readOnly;
98      //innerList = new System.Collections.ObjectModel.ReadOnlyCollection<T>(baseCollection);
99      innerList.AddRange(baseCollection);
100    }
101
102
103
104
105    #endregion
106
107    /// <summary>
108    /// Shows the string representation of the collection. The string representation contains
109    /// a list of the items in the collection. Contained collections (except string) are expanded
110    /// recursively.
111    /// </summary>
112    /// <returns>The string representation of the collection.</returns>
113    public override string ToString() {
114      return Algorithms.ToString(this);
115    }
116    /// <summary>
117    /// Returns a string representation of this collection.
118    /// </summary>
119    /// <param name="format">The format.</param>
120    /// <param name="formatProvider">The format provider.</param>
121    /// <returns></returns>
122    public virtual string ToString(string format, IFormatProvider formatProvider) {
123      return Showing.ShowString(this, format, formatProvider);
124    }
125
126    #region ICollection<T> Members
127
128    /// <summary>
129    /// Must be overridden to allow adding items to this collection.
130    /// </summary>
131    /// <remarks><p>This method is not abstract, although derived classes should always
132    /// override it. It is not abstract because some derived classes may wish to reimplement
133    /// Add with a different return type (typically bool). In C#, this can be accomplished
134    /// with code like the following:</p>
135    /// <code>
136    ///     public class MyCollection&lt;T&gt;: CollectionBase&lt;T&gt;, ICollection&lt;T&gt;
137    ///     {
138    ///         public new bool Add(T item) {
139    ///             /* Add the item */
140    ///         }
141    /// 
142    ///         void ICollection&lt;T&gt;.Add(T item) {
143    ///             Add(item);
144    ///         }
145    ///     }
146    /// </code>
147    /// </remarks>
148    /// <param name="item">Item to be added to the collection.</param>
149    /// <exception cref="NotImplementedException">Always throws this exception to indicated
150    /// that the method must be overridden or re-implemented in the derived class.</exception>
151    public virtual void Add(T item) {
152      if (item == null) throw new InconsistencyException("Adding 'null' to the collection is not allowed.");
153      if (mReadOnly)
154        throw new InconsistencyException("The collection is read only");
155      this.innerList.Add(item);
156      RaiseOnItemAdded(item);
157
158    }
159    /// <summary>
160    /// Determines the index of a specific item in the <see cref="T:System.Collections.Generic.IList`1"></see>.
161    /// </summary>
162    /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.IList`1"></see>.</param>
163    /// <returns>
164    /// The index of item if found in the list; otherwise, -1.
165    /// </returns>
166    public int IndexOf(T item) {
167      return this.innerList.IndexOf(item);
168    }
169
170    /// <summary>
171    /// Inserts the specified item at the specified index.
172    /// </summary>
173    /// <param name="index">The index.</param>
174    /// <param name="item">A parameter of the generics Type T</param>
175    public virtual void Insert(int index, T item) {
176      if (mReadOnly)
177        throw new InconsistencyException("The collection is read only");
178      if (item.Equals(default(T)))
179        return;
180      this.innerList.Insert(index, item);
181      RaiseOnItemAdded(item);
182    }
183
184    /// <summary>
185    /// Adds a collection range to this collection.
186    /// </summary>
187    /// <param name="items">The items.</param>
188    public virtual void AddRange(CollectionBase<T> items) {
189      if (mReadOnly)
190        throw new InconsistencyException("The collection is read only");
191      this.innerList.AddRange(items);
192      foreach (T item in items) {
193        RaiseOnItemAdded(item);
194      }
195    }
196
197    private void RaiseOnItemAdded(T item) {
198      if (OnItemAdded != null)
199        OnItemAdded(this, new CollectionEventArgs<T>(item));
200    }
201
202    private void RaiseOnItemRemoved(T item) {
203      if (OnItemRemoved != null)
204        OnItemRemoved(this, new CollectionEventArgs<T>(item));
205    }
206    private void RaiseOnClear() {
207      if (OnClear != null)
208        OnClear(this, EventArgs.Empty);
209    }
210
211
212
213    /// <summary>
214    /// Must be overridden to allow clearing this collection.
215    /// </summary>
216    public virtual void Clear() {
217      RaiseOnClear();
218      innerList.Clear();
219    }
220
221    /// <summary>
222    /// Must be overridden to allow removing items from this collection.
223    /// </summary>
224    /// <returns>True if <paramref name="item"/> existed in the collection and
225    /// was removed. False if <paramref name="item"/> did not exist in the collection.</returns>
226    public virtual bool Remove(T item) {
227
228      bool result = this.innerList.Remove(item);
229      if (result) {
230        RaiseOnItemRemoved(item);
231      }
232      return result;
233    }
234
235    /// <summary>
236    /// Determines if the collection contains a particular item. This default implementation
237    /// iterates all of the items in the collection via GetEnumerator, testing each item
238    /// against <paramref name="item"/> using IComparable&lt;T&gt;.Equals or
239    /// Object.Equals.
240    /// </summary>
241    /// <remarks>You should strongly consider overriding this method to provide
242    /// a more efficient implementation, or if the default equality comparison
243    /// is inappropriate.</remarks>
244    /// <param name="item">The item to check for in the collection.</param>
245    /// <returns>True if the collection contains <paramref name="item"/>, false otherwise.</returns>
246    public virtual bool Contains(T item) {
247      return this.innerList.Contains(item);
248
249    }
250
251    /// <summary>
252    /// Copies all the items in the collection into an array. Implemented by
253    /// using the enumerator returned from GetEnumerator to get all the items
254    /// and copy them to the provided array.
255    /// </summary>
256    /// <param name="array">Array to copy to.</param>
257    /// <param name="arrayIndex">Starting index in <paramref name="array"/> to copy to.</param>
258    public virtual void CopyTo(T[] array, int arrayIndex) {
259      int count = this.Count;
260
261      if (count == 0)
262        return;
263
264      if (array == null)
265        throw new ArgumentNullException("array");
266      if (count < 0)
267        throw new ArgumentOutOfRangeException("count", count, Resource1.ArgumentOutOfRange);
268      if (arrayIndex < 0)
269        throw new ArgumentOutOfRangeException("arrayIndex", arrayIndex, Resource1.ArgumentOutOfRange);
270      if (arrayIndex >= array.Length || count > array.Length - arrayIndex)
271        throw new ArgumentException("arrayIndex", Resource1.ArrayTooSmall);
272
273      int index = arrayIndex, i = 0;
274      foreach (T item in (ICollection<T>)this) {
275        if (i >= count)
276          break;
277
278        array[index] = item;
279        ++index;
280        ++i;
281      }
282    }
283
284    /// <summary>
285    /// Creates an array of the correct size, and copies all the items in the
286    /// collection into the array, by calling CopyTo.
287    /// </summary>
288    /// <returns>An array containing all the elements in the collection, in order.</returns>
289    public virtual T[] ToArray() {
290      int count = this.Count;
291
292      T[] array = new T[count];
293      CopyTo(array, 0);
294      return array;
295    }
296
297    /// <summary>
298    /// Must be overridden to provide the number of items in the collection.
299    /// </summary>
300    /// <value>The number of items in the collection.</value>
301    public virtual int Count { get { return innerList.Count; } }
302
303
304
305    #endregion
306
307    #region Delegate operations
308
309    /// <summary>
310    /// Determines if the collection contains any item that satisfies the condition
311    /// defined by <paramref name="predicate"/>.
312    /// </summary>
313    /// <param name="predicate">A delegate that defines the condition to check for.</param>
314    /// <returns>True if the collection contains one or more items that satisfy the condition
315    /// defined by <paramref name="predicate"/>. False if the collection does not contain
316    /// an item that satisfies <paramref name="predicate"/>.</returns>
317    public virtual bool Exists(Predicate<T> predicate) {
318      if (predicate == null)
319        throw new ArgumentNullException("predicate");
320
321      return Algorithms.Exists(this, predicate);
322    }
323
324    /// <summary>
325    /// Determines if all of the items in the collection satisfy the condition
326    /// defined by <paramref name="predicate"/>.
327    /// </summary>
328    /// <param name="predicate">A delegate that defines the condition to check for.</param>
329    /// <returns>True if all of the items in the collection satisfy the condition
330    /// defined by <paramref name="predicate"/>, or if the collection is empty. False if one or more items
331    /// in the collection do not satisfy <paramref name="predicate"/>.</returns>
332    public virtual bool TrueForAll(Predicate<T> predicate) {
333      if (predicate == null)
334        throw new ArgumentNullException("predicate");
335
336      return Algorithms.TrueForAll(this, predicate);
337    }
338    /*
339   /// <summary>
340   /// Counts the number of items in the collection that satisfy the condition
341   /// defined by <paramref name="predicate"/>.
342   /// </summary>
343   /// <param name="predicate">A delegate that defines the condition to check for.</param>
344   /// <returns>The number of items in the collection that satisfy <paramref name="predicate"/>.</returns>
345   public virtual int CountWhere(Predicate<T> predicate)
346   {
347       if (predicate == null)
348           throw new ArgumentNullException("predicate");
349
350       return Algorithms.CountWhere(this, predicate);
351   }
352     */
353    /// <summary>
354    /// Finds the first item in the collection satisfying the given predicate
355    /// </summary>
356    /// <param name="predicate">a searching predictae</param>
357    /// <returns>an item satisfying the criteria (if any)</returns>
358    public virtual T Find(Predicate<T> predicate) {
359      foreach (T item in this.innerList) {
360        if (predicate(item))
361          return item;
362      }
363      return default(T);
364    }
365
366
367    /// <summary>
368    /// Removes all the items in the collection that satisfy the condition
369    /// defined by <paramref name="predicate"/>.
370    /// </summary>
371    /// <param name="predicate">A delegate that defines the condition to check for.</param>
372    /// <returns>Returns a collection of the items that were removed, in sorted order.</returns>
373    public virtual ICollection<T> RemoveAll(Predicate<T> predicate) {
374      if (predicate == null)
375        throw new ArgumentNullException("predicate");
376
377      return Algorithms.RemoveWhere(this, predicate);
378    }
379
380    /// <summary>
381    /// Performs the specified action on each item in this collection.
382    /// </summary>
383    /// <param name="action">An Action delegate which is invoked for each item in this collection.</param>
384    public virtual void ForEach(Action<T> action) {
385      if (action == null)
386        throw new ArgumentNullException("action");
387
388      Algorithms.ForEach(this, action);
389    }
390
391
392
393    #endregion
394
395    #region IEnumerable<T> Members
396
397    /// <summary>
398    /// Must be overridden to enumerate all the members of the collection.
399    /// </summary>
400    /// <returns>A generic IEnumerator&lt;T&gt; that can be used
401    /// to enumerate all the items in the collection.</returns>
402    public virtual IEnumerator<T> GetEnumerator() {
403      return this.innerList.GetEnumerator();
404    }
405
406
407    #endregion
408
409    #region ICollection Members
410
411    /// <summary>
412    /// Copies all the items in the collection into an array. Implemented by
413    /// using the enumerator returned from GetEnumerator to get all the items
414    /// and copy them to the provided array.
415    /// </summary>
416    /// <param name="array">Array to copy to.</param>
417    /// <param name="index">Starting index in <paramref name="array"/> to copy to.</param>
418    void ICollection.CopyTo(Array array, int index) {
419      int count = this.Count;
420
421      if (count == 0)
422        return;
423
424      if (array == null)
425        throw new ArgumentNullException("array");
426      if (index < 0)
427        throw new ArgumentOutOfRangeException("index", index, Resource1.ArgumentOutOfRange);
428      if (index >= array.Length || count > array.Length - index)
429        throw new ArgumentException("index", Resource1.ArrayTooSmall);
430
431      int i = 0;
432      foreach (object o in (ICollection)this) {
433        if (i >= count)
434          break;
435
436        array.SetValue(o, index);
437        ++index;
438        ++i;
439      }
440    }
441
442    /// <summary>
443    /// Indicates whether the collection is synchronized.
444    /// </summary>
445    /// <value>Always returns false, indicating that the collection is not synchronized.</value>
446    bool ICollection.IsSynchronized {
447      get { return IsSynchronized; }
448    }
449
450    /// <summary>
451    /// See code analysis CA1033
452    /// </summary>
453    protected bool IsSynchronized {
454      get { return false; }
455    }
456    /// <summary>
457    /// Indicates the synchronization object for this collection.
458    /// </summary>
459    /// <value>Always returns this.</value>
460    object ICollection.SyncRoot {
461      get { return SyncRoot; }
462    }
463
464    /// <summary>
465    /// See code analysis CA1033
466    /// </summary>
467    protected object SyncRoot {
468      get { return this; }
469    }
470
471    #endregion
472
473    #region IEnumerable Members
474
475    /// <summary>
476    /// Provides an IEnumerator that can be used to iterate all the members of the
477    /// collection. This implementation uses the IEnumerator&lt;T&gt; that was overridden
478    /// by the derived classes to enumerate the members of the collection.
479    /// </summary>
480    /// <returns>An IEnumerator that can be used to iterate the collection.</returns>
481    IEnumerator IEnumerable.GetEnumerator() {
482      foreach (T item in this) {
483        yield return item;
484      }
485    }
486
487    #endregion
488
489    /// <summary>
490    /// Display the contents of the collection in the debugger. This is intentionally private, it is called
491    /// only from the debugger due to the presence of the DebuggerDisplay attribute. It is similar
492    /// format to ToString(), but is limited to 250-300 characters or so, so as not to overload the debugger.
493    /// </summary>
494    /// <returns>The string representation of the items in the collection, similar in format to ToString().</returns>
495    internal string DebuggerDisplayString() {
496      const int MAXLENGTH = 250;
497
498      System.Text.StringBuilder builder = new System.Text.StringBuilder();
499
500      builder.Append('{');
501
502      // Call ToString on each item and put it in.
503      bool firstItem = true;
504      foreach (T item in this) {
505        if (builder.Length >= MAXLENGTH) {
506          builder.Append(",...");
507          break;
508        }
509
510        if (!firstItem)
511          builder.Append(',');
512
513        if (item == null)
514          builder.Append("null");
515        else
516          builder.Append(item.ToString());
517
518        firstItem = false;
519      }
520
521      builder.Append('}');
522      return builder.ToString();
523    }
524    /// <summary>
525    /// Removes an item at the given index
526    /// </summary>
527    /// <param name="index"></param>
528    public void RemoveAt(int index) {
529      this.innerList.RemoveAt(index);
530    }
531    /// <summary>
532    /// Integer indexer
533    /// </summary>
534    /// <param name="index"></param>
535    /// <returns></returns>
536    public T this[int index] {
537      get {
538        return this.innerList[index];
539      }
540      set {
541        this.innerList[index] = value;
542      }
543    }
544
545    /// <summary>
546    /// Returns a deep copy of this collection.
547    /// <remarks>The returned collection is not attached to the <see cref="Model"/>
548    /// and is as such on an in-memory collection of instances. You need to 'unwrap' the collection
549    /// in the model and, to make it visible, deploy it in the paintables collection of the model.
550    /// </remarks>
551    /// </summary>
552    /// <returns></returns>
553    public CollectionBase<T> DeepCopy() {
554      /* This doesn't work seemingly....
555      if (!typeof(T).IsSerializable)
556          throw new InconsistencyException("The generic type on which the collection is based is not serializable, the collection cannot generate a deep copy.");
557      */
558
559      try {
560
561        CollectionBase<T> newobj = null;
562        MemoryStream stream = new MemoryStream();
563        GenericFormatter<BinaryFormatter> f = new GenericFormatter<BinaryFormatter>();
564        f.Serialize(stream, this);
565        stream.Seek(0, SeekOrigin.Begin);
566        newobj = f.Deserialize<CollectionBase<T>>(stream);
567        stream.Close();
568        return newobj;
569      }
570      catch (Exception exc) {
571        throw new InconsistencyException("The copy operation failed.", exc);
572      }
573
574    }
575    /// <summary>
576    /// Returns a copy of this instance.
577    /// </summary>
578    /// <returns></returns>
579    public CollectionBase<T> Copy() {
580      CollectionBase<T> copy = new CollectionBase<T>();
581      foreach (T item in this.innerList) {
582        copy.Add(item);
583      }
584      return copy;
585    }
586    /// <summary>
587    /// This method creates first a deep copy of the collection and puts
588    /// the result in a <see cref="MemoryStream"/>.
589    /// See the <see cref="CopyTool"/> for details.
590    /// </summary>
591    /// <returns></returns>
592    public MemoryStream ToStream() {
593      try {
594
595        MemoryStream stream = new MemoryStream();
596        GenericFormatter<BinaryFormatter> f =
597            new GenericFormatter<BinaryFormatter>();
598        f.Serialize(stream, this);
599        return stream;
600      }
601      catch (Exception exc) {
602        throw new InconsistencyException(
603            "The ToStream() operation failed.",
604            exc);
605      }
606
607    }
608
609    /// <summary>
610    /// Format <code>this</code> using at most approximately <code>rest</code> chars and
611    /// append the result, possibly truncated, to stringbuilder.
612    /// Subtract the actual number of used chars from <code>rest</code>.
613    /// </summary>
614    /// <param name="stringbuilder"></param>
615    /// <param name="rest"></param>
616    /// <param name="formatProvider"></param>
617    /// <returns>
618    /// True if the appended formatted string was complete (not truncated).
619    /// </returns>
620    public virtual bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider) {
621      return true;
622    }
623
624  }
625
626
627
628
629
630
631}
Note: See TracBrowser for help on using the repository browser.