Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Data/3.3/ItemDictionary_T.cs @ 2526

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

Refactored cloning (#806)

File size: 11.1 KB
Line 
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Text;
5using System.Xml;
6using HeuristicLab.Core;
7using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
8using HeuristicLab.Common;
9
10namespace HeuristicLab.Data {
11  /// <summary>
12  /// A dictionary having key-value pairs of the type <see cref="IItem"/>.
13  /// </summary>
14  /// <typeparam name="K">The type of the keys, which must implement the interface <see cref="IItem"/>.</typeparam>
15  /// <typeparam name="V">The type of the values, which must imlement the interface <see cref="IItem"/>.</typeparam>
16  public class ItemDictionary<K,V> : ItemBase, IDictionary<K,V>
17    where K : IItem
18    where V : IItem {
19
20    [Storable]
21    private Dictionary<K, V> dict;
22
23    /// <summary>
24    /// Gets the dictionary of key-value pairs.
25    /// </summary>
26    public Dictionary<K, V> Dictionary {
27      get { return dict; }
28    }
29
30    /// <summary>
31    /// Initializes a new instance of <see cref="ItemDictionary&lt;TKey,TValue&gt;"/>.
32    /// </summary>
33    /// <remarks>Creates a new <see cref="Dictionary"/>
34    /// having <see cref="IItem"/> as type of keys and values
35    /// and a new <see cref="IItemKeyComparer&lt;T&gt;"/> as <see cref="IEqualityComparer"/>.</remarks>
36    public ItemDictionary() {
37      dict = new Dictionary<K, V>(new IItemKeyComparer<K>());
38    }
39
40    #region ItemBase Members
41    /// <summary>
42    /// Clones the current instance and adds it to the dictionary <paramref name="clonedObjects"/>.
43    /// </summary>
44    /// <remarks>Also the keys and values in the dictionary are cloned and saved to the dictionary <paramref name="clonedObjects"/>,
45    /// when they are not already contained (deep copy).</remarks>
46    /// <param name="clonedObjects">A dictionary of all already cloned objects.</param>
47    /// <returns>The cloned instance as <see cref="ItemDictionary&lt;K,V&gt;"/>.</returns>
48    public override IItem Clone(ICloner cloner) {
49      ItemDictionary<K,V> clone = new ItemDictionary<K,V>();
50      cloner.RegisterClonedObject(this, clone);
51      foreach (KeyValuePair<K, V> item in dict) {
52        clone.dict.Add((K) cloner.Clone(item.Key), (V) cloner.Clone(item.Value));
53      }
54      return clone;
55    }
56
57    /// <summary>
58    /// The string representation of the dictionary
59    /// </summary>
60    /// <returns>The elements of the dictionary as string, each key-value pair in the format
61    /// <c>Key:Value</c>, separated by a semicolon. <br/>
62    /// If the dictionary contains no entries, "Empty Dictionary" is returned.</returns>
63    public override string ToString() {
64      if (dict.Count > 0) {
65        StringBuilder builder = new StringBuilder();
66        foreach (KeyValuePair<K, V> item in dict) {
67          builder.Append(item.Key.ToString());
68          builder.Append(":");
69          builder.Append(item.Value.ToString());
70          builder.Append("; ");
71        }
72        return builder.ToString();
73      } else {
74        return "Empty Dictionary";
75      }
76    }
77    #endregion
78
79    #region IDictionary<K,V> Members
80
81    ///// <summary>
82    ///// Adds a new key value pair to the dictionary.
83    ///// </summary>
84    /// <inheritdoc cref="System.Collections.Generic.Dictionary&lt;K,V&gt;.Add"/>
85    /// <remarks>Calls <see cref="OnItemAdded"/>.</remarks>
86    ///// <param name="key">The key to add.</param>
87    ///// <param name="value">The value to add.</param>
88    public void Add(K key, V value) {
89      dict.Add(key, value);
90      OnItemAdded(key, value);
91    }
92
93    /// <inheritdoc cref="System.Collections.Generic.Dictionary&lt;TKey,TValue&gt;.ContainsKey"/>
94    public bool ContainsKey(K key) {
95      return dict.ContainsKey(key);
96    }
97
98    /// <inheritdoc cref="System.Collections.Generic.Dictionary&lt;TKey,TValue&gt;.Keys"/>
99    public ICollection<K> Keys {
100      get { return dict.Keys; }
101    }
102
103    /// <summary>
104    /// Removes a key-value pair having the specified <paramref name="key"/>.
105    /// </summary>
106    /// <remarks>Calls <see cref="OnItemRemoved"/>.</remarks>
107    /// <param name="key">The key of the key-value pair, which should be removed.</param>
108    /// <returns><c>true</c> if the key was found and successfully removed,
109    /// <c>false</c> if the key was not found.</returns>
110    public bool Remove(K key) {
111      V value = dict[key];
112      bool removed = dict.Remove(key);
113      OnItemRemoved(key, value);
114      return removed;
115    }
116
117    /// <inheritdoc cref="System.Collections.Generic.Dictionary&lt;K,V&gt;.TryGetValue"/>
118    public bool TryGetValue(K key, out V value) {
119      return dict.TryGetValue(key, out value);
120    }
121
122    /// <inheritdoc cref="System.Collections.Generic.Dictionary&lt;TKey,TValue&gt;.Values"/>
123    public ICollection<V> Values {
124      get { return dict.Values; }
125    }
126
127    /// <summary>
128    /// Gets or sets the value of a specified <paramref name="key"/>.
129    /// </summary>
130    /// <param name="key">The key of the value which should be received or changed.</param>
131    /// <returns>The value of the <paramref name="key"/>.</returns>
132    public V this[K key] {
133      get { return dict[key]; }
134      set { dict[key] = value; }
135    }
136
137    #endregion
138
139    #region ICollection<KeyValuePair<K,V>> Members
140
141    /// <summary>
142    /// Adds a key-value pair to the current instance.
143    /// </summary>
144    /// <remarks>Calls <see cref="OnItemAdded"/>.</remarks>
145    /// <param name="item">The key-value pair to add.</param>
146    public void Add(KeyValuePair<K, V> item) {
147      dict.Add(item.Key, item.Value);
148      OnItemAdded(item.Key, item.Value);
149    }
150
151    ///// <summary>
152    ///// Empties the dictionary.
153    ///// </summary>
154    /// <inheritdoc cref="System.Collections.Generic.Dictionary&lt;K,V&gt;.Clear"/>
155    /// <remarks>Calls <see cref="OnCleared"/>.</remarks>
156    public void Clear() {
157      dict.Clear();
158      OnCleared();
159    }
160
161    /// <summary>
162    /// Checks whether the specified key-value pair exists in the current instance of the dictionary.
163    /// </summary>
164    /// <param name="item">The key-value pair to check.</param>
165    /// <returns><c>true</c> if both, the key and the value exist in the dictionary,
166    /// <c>false</c> otherwise.</returns>
167    public bool Contains(KeyValuePair<K, V> item) {
168      return (dict.ContainsKey(item.Key) && dict[item.Key].Equals(item.Value));
169    }
170
171    /// <summary>
172    /// TODO
173    /// </summary>
174    /// <param name="array"></param>
175    /// <param name="arrayIndex"></param>
176    public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex) {
177      throw new NotImplementedException();
178    }
179
180    /// <inheritdoc cref="System.Collections.Generic.Dictionary&lt;K,V&gt;.Count"/>
181    public int Count {
182      get { return dict.Count; }
183    }
184
185    /// <summary>
186    /// Checks whether the dictionary is read-only.
187    /// </summary>
188    /// <remarks>Always returns <c>false</c>.</remarks>
189    public bool IsReadOnly {
190      get { return false; }
191    }
192
193    /// <summary>
194    /// Removes the specified key-value pair.
195    /// </summary>
196    /// <remarks>Calls <see cref="OnItemRemoved"/> when the removal was successful.</remarks>
197    /// <param name="item">The key-value pair to remove.</param>
198    /// <returns><c>true</c> if the removal was successful, <c>false</c> otherwise.</returns>
199    public bool Remove(KeyValuePair<K, V> item) {
200      bool removed = dict.Remove(item.Key);
201      if (removed) {
202        OnItemRemoved(item.Key, item.Value);
203      }
204      return removed;
205    }
206    #endregion
207
208    #region IEnumerable<KeyValuePair<K,V>> Members
209    /// <inheritdoc cref="System.Collections.Generic.Dictionary&lt;K,V&gt;.GetEnumerator"/>
210    public IEnumerator<KeyValuePair<K, V>> GetEnumerator() {
211      return dict.GetEnumerator();
212    }
213    #endregion
214
215    #region IEnumerable Members
216    /// <inheritdoc cref="System.Collections.Generic.Dictionary&lt;K,V&gt;.GetEnumerator"/>
217    IEnumerator IEnumerable.GetEnumerator() {
218      return dict.GetEnumerator();
219    }
220    #endregion
221
222    #region Event Handler
223    /// <summary>
224    /// Occurs when a new item is added to the dictionary.
225    /// </summary>
226    public event EventHandler<EventArgs<IItem, IItem>> ItemAdded;
227    /// <summary>
228    /// Fires a new <c>ItemAdded</c> event.
229    /// </summary>
230    /// <remarks>Calls <see cref="HeuristicLab.Core.ItemBase.OnChanged"/>.</remarks>
231    /// <param name="key">The key that was added.</param>
232    /// <param name="value">The value that was added.</param>
233    protected virtual void OnItemAdded(K key, V value) {
234      if (ItemAdded != null)
235        ItemAdded(this, new EventArgs<IItem, IItem>(key, value));
236      OnChanged();
237    }
238
239    /// <summary>
240    /// Occurs when an item is removed from the dictionary.
241    /// </summary>
242    public event EventHandler<EventArgs<IItem, IItem>> ItemRemoved;
243    /// <summary>
244    /// Fires a new <c>ItemRemoved</c> event.
245    /// </summary>
246    /// <remarks>Calls <see cref="HeuristicLab.Core.ItemBase.OnChanged"/>.</remarks>
247    /// <param name="key">The key that was removed.</param>
248    /// <param name="value">The value that was removed</param>
249    protected virtual void OnItemRemoved(K key, V value) {
250      if (ItemRemoved != null)
251        ItemRemoved(this, new EventArgs<IItem, IItem>(key, value));
252      OnChanged();
253    }
254
255    /// <summary>
256    /// Occurs when the dictionary is emptied.
257    /// </summary>
258    public event EventHandler Cleared;
259    /// <summary>
260    /// Fires a new <c>Cleared</c> event.
261    /// </summary>
262    /// <remarks>Calls <see cref="HeuristicLab.Core.ItemBase.OnChanged"/>.</remarks>
263    protected virtual void OnCleared() {
264      if (Cleared != null)
265        Cleared(this, new EventArgs());
266      OnChanged();
267    }
268    #endregion
269
270    #region IEqualityComparer
271    /// <summary>
272    /// Compares two keys with each other.
273    /// </summary>
274    /// <typeparam name="T">The type of the keys.</typeparam>
275    internal sealed class IItemKeyComparer<T> : IEqualityComparer<T>
276        where T : IItem {
277      /// <summary>
278      /// Checks whether two keys are equal to each other.
279      /// </summary>
280      /// <param name="x">Key number one.</param>
281      /// <param name="y">Key number two.</param>
282      /// <returns><c>true</c> if the two keys are the same, <c>false</c> otherwise.</returns>
283      public bool Equals(T x, T y) {
284        if (x is IComparable) {
285          return (((IComparable) x).CompareTo(y) == 0);
286        }
287        if (y is IComparable) {
288          return (((IComparable) y).CompareTo(x) == 0);
289        }
290        return x.Equals(y);
291      }
292
293      /// <summary>
294      /// Serves as a hash function for a particular type.
295      /// </summary>
296      /// <param name="obj">The object where the hash code is searched for.</param>
297      /// <returns>A hash code for the given <paramref name="obj"/>.</returns>
298      public int GetHashCode(T obj) {
299        if (obj is IObjectData) {
300          return ((IObjectData) obj).Data.GetHashCode();
301        }
302        return obj.GetHashCode();
303      }
304    }
305    #endregion
306  }
307}
Note: See TracBrowser for help on using the repository browser.