using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Xml; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Common; namespace HeuristicLab.Data { /// /// A dictionary having key-value pairs of the type . /// /// The type of the keys, which must implement the interface . /// The type of the values, which must imlement the interface . public class ItemDictionary : ItemBase, IDictionary where K : IItem where V : IItem { [Storable] private Dictionary dict; /// /// Gets the dictionary of key-value pairs. /// public Dictionary Dictionary { get { return dict; } } /// /// Initializes a new instance of . /// /// Creates a new /// having as type of keys and values /// and a new as . public ItemDictionary() { dict = new Dictionary(new IItemKeyComparer()); } #region ItemBase Members /// /// Clones the current instance and adds it to the dictionary . /// /// Also the keys and values in the dictionary are cloned and saved to the dictionary , /// when they are not already contained (deep copy). /// A dictionary of all already cloned objects. /// The cloned instance as . public override IItem Clone(ICloner cloner) { ItemDictionary clone = new ItemDictionary(); cloner.RegisterClonedObject(this, clone); foreach (KeyValuePair item in dict) { clone.dict.Add((K) cloner.Clone(item.Key), (V) cloner.Clone(item.Value)); } return clone; } /// /// The string representation of the dictionary /// /// The elements of the dictionary as string, each key-value pair in the format /// Key:Value, separated by a semicolon.
/// If the dictionary contains no entries, "Empty Dictionary" is returned.
public override string ToString() { if (dict.Count > 0) { StringBuilder builder = new StringBuilder(); foreach (KeyValuePair item in dict) { builder.Append(item.Key.ToString()); builder.Append(":"); builder.Append(item.Value.ToString()); builder.Append("; "); } return builder.ToString(); } else { return "Empty Dictionary"; } } #endregion #region IDictionary Members ///// ///// Adds a new key value pair to the dictionary. ///// /// /// Calls . ///// The key to add. ///// The value to add. public void Add(K key, V value) { dict.Add(key, value); OnItemAdded(key, value); } /// public bool ContainsKey(K key) { return dict.ContainsKey(key); } /// public ICollection Keys { get { return dict.Keys; } } /// /// Removes a key-value pair having the specified . /// /// Calls . /// The key of the key-value pair, which should be removed. /// true if the key was found and successfully removed, /// false if the key was not found. public bool Remove(K key) { V value = dict[key]; bool removed = dict.Remove(key); OnItemRemoved(key, value); return removed; } /// public bool TryGetValue(K key, out V value) { return dict.TryGetValue(key, out value); } /// public ICollection Values { get { return dict.Values; } } /// /// Gets or sets the value of a specified . /// /// The key of the value which should be received or changed. /// The value of the . public V this[K key] { get { return dict[key]; } set { dict[key] = value; } } #endregion #region ICollection> Members /// /// Adds a key-value pair to the current instance. /// /// Calls . /// The key-value pair to add. public void Add(KeyValuePair item) { dict.Add(item.Key, item.Value); OnItemAdded(item.Key, item.Value); } ///// ///// Empties the dictionary. ///// /// /// Calls . public void Clear() { dict.Clear(); OnCleared(); } /// /// Checks whether the specified key-value pair exists in the current instance of the dictionary. /// /// The key-value pair to check. /// true if both, the key and the value exist in the dictionary, /// false otherwise. public bool Contains(KeyValuePair item) { return (dict.ContainsKey(item.Key) && dict[item.Key].Equals(item.Value)); } /// /// TODO /// /// /// public void CopyTo(KeyValuePair[] array, int arrayIndex) { throw new NotImplementedException(); } /// public int Count { get { return dict.Count; } } /// /// Checks whether the dictionary is read-only. /// /// Always returns false. public bool IsReadOnly { get { return false; } } /// /// Removes the specified key-value pair. /// /// Calls when the removal was successful. /// The key-value pair to remove. /// true if the removal was successful, false otherwise. public bool Remove(KeyValuePair item) { bool removed = dict.Remove(item.Key); if (removed) { OnItemRemoved(item.Key, item.Value); } return removed; } #endregion #region IEnumerable> Members /// public IEnumerator> GetEnumerator() { return dict.GetEnumerator(); } #endregion #region IEnumerable Members /// IEnumerator IEnumerable.GetEnumerator() { return dict.GetEnumerator(); } #endregion #region Event Handler /// /// Occurs when a new item is added to the dictionary. /// public event EventHandler> ItemAdded; /// /// Fires a new ItemAdded event. /// /// Calls . /// The key that was added. /// The value that was added. protected virtual void OnItemAdded(K key, V value) { if (ItemAdded != null) ItemAdded(this, new EventArgs(key, value)); OnChanged(); } /// /// Occurs when an item is removed from the dictionary. /// public event EventHandler> ItemRemoved; /// /// Fires a new ItemRemoved event. /// /// Calls . /// The key that was removed. /// The value that was removed protected virtual void OnItemRemoved(K key, V value) { if (ItemRemoved != null) ItemRemoved(this, new EventArgs(key, value)); OnChanged(); } /// /// Occurs when the dictionary is emptied. /// public event EventHandler Cleared; /// /// Fires a new Cleared event. /// /// Calls . protected virtual void OnCleared() { if (Cleared != null) Cleared(this, new EventArgs()); OnChanged(); } #endregion #region IEqualityComparer /// /// Compares two keys with each other. /// /// The type of the keys. internal sealed class IItemKeyComparer : IEqualityComparer where T : IItem { /// /// Checks whether two keys are equal to each other. /// /// Key number one. /// Key number two. /// true if the two keys are the same, false otherwise. public bool Equals(T x, T y) { if (x is IComparable) { return (((IComparable) x).CompareTo(y) == 0); } if (y is IComparable) { return (((IComparable) y).CompareTo(x) == 0); } return x.Equals(y); } /// /// Serves as a hash function for a particular type. /// /// The object where the hash code is searched for. /// A hash code for the given . public int GetHashCode(T obj) { if (obj is IObjectData) { return ((IObjectData) obj).Data.GetHashCode(); } return obj.GetHashCode(); } } #endregion } }