//! \file GameRes.cs //! \date Mon Jun 30 20:12:13 2014 //! \brief game resources browser. // // copy-pasted from some post on the stackoverflow. // using System; using System.Collections.Generic; namespace GameRes.Collections { /// /// Extension to the normal Dictionary. This class can store more than one value for every key. /// It keeps a HashSet for every Key value. Calling Add with the same Key and multiple values /// will store each value under the same Key in the Dictionary. Obtaining the values for a Key /// will return the HashSet with the Values of the Key. /// /// The type of the key. /// The type of the value. public class MultiValueDictionary : Dictionary> //, IEnumerable>, System.Collections.IEnumerable { /// /// Initializes a new instance of the class. /// public MultiValueDictionary() : base() { } /// /// Adds the specified value under the specified key /// /// The key. /// The value. public void Add(TKey key, TValue value) { HashSet container = null; if(!this.TryGetValue(key, out container)) { container = new HashSet(); base.Add(key, container); } container.Add(value); } /// /// Removes the specified value for the specified key. It will leave the key in the dictionary. /// /// The key. /// The value. public void Remove(TKey key, TValue value) { HashSet container = null; if(this.TryGetValue(key, out container)) { container.Remove(value); if(container.Count <= 0) { this.Remove(key); } } } /// /// Gets the values for the key specified. This method is useful if you want to avoid an /// exception for key value retrieval and you can't use TryGetValue (e.g. in lambdas) /// /// The key. /// if set to true and the key isn't found, an empty hashset is /// returned, otherwise, if the key isn't found, null is returned /// /// This method will return null (or an empty set if returnEmptySet is true) if the key /// wasn't found, or the values if key was found. /// public HashSet GetValues(TKey key, bool returnEmptySet) { HashSet toReturn = null; if (!base.TryGetValue(key, out toReturn) && returnEmptySet) { toReturn = new HashSet(); } return toReturn; } /* // hides Dictionary.GetEnumerator() new public IEnumerator> GetEnumerator() { Enumerator e = new Enumerator(); e.key_enumerator = base.GetEnumerator(); e.current_pair = new KeyValuePair(); if (e.key_enumerator.MoveNext()) e.value_enumerator = e.key_enumerator.Current.Value.GetEnumerator(); else e.value_enumerator = null; return e; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return (System.Collections.IEnumerator)GetEnumerator(); } [SerializableAttribute] new public struct Enumerator : IEnumerator>, IDisposable, System.Collections.IEnumerator { public Dictionary>.Enumerator key_enumerator; public HashSet.Enumerator? value_enumerator; public KeyValuePair current_pair; public KeyValuePair Current { get { return current_pair; } } object System.Collections.IEnumerator.Current { get { return Current; } } void IDisposable.Dispose() { } void System.Collections.IEnumerator.Reset() { } private void SetCurrent () { current_pair = new KeyValuePair(key_enumerator.Current.Key, value_enumerator.Value.Current); Console.WriteLine("Enumerator.SetCurrent ({0} => {1})", current_pair.Key, current_pair.Value); } private void ResetCurrent () { current_pair = new KeyValuePair(default(TKey), default(TValue)); } public bool MoveNext () { if (null == value_enumerator) { ResetCurrent(); return false; } if (value_enumerator.Value.MoveNext()) { SetCurrent(); return true; } if (!key_enumerator.MoveNext()) { value_enumerator = null; ResetCurrent(); return false; } value_enumerator = key_enumerator.Current.Value.GetEnumerator(); if (value_enumerator.Value.MoveNext()) { SetCurrent(); return true; } else { current_pair = new KeyValuePair(key_enumerator.Current.Key, default(TValue)); return false; } } } */ } }