Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Persistence Test/HeuristicLab.Data/3.3/ItemDictionary_T.cs @ 3362

Last change on this file since 3362 was 2474, checked in by swagner, 15 years ago

Implemented generic EventArgs (#796)

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