using System; using System.Collections.Generic; using System.Linq; using System.Text; #pragma warning disable CS8601 // Possible null reference assignment. #pragma warning disable CS8602 // Dereference of a possibly null reference. #pragma warning disable CS8603 // Possible null reference return. #pragma warning disable CS8604 // Possible null reference argument. #pragma warning disable CS8605 // Unboxing a possibly null value. #pragma warning disable CS8618 // Non-nullable property 'Text' must contain a non-null value when exiting constructor. Consider declaring the property as nullable. #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. namespace EasyDevCore.Common.Wrapper { /// /// Represents a collection of keys and values. You can add multiple values to the same key. /// /// The type of the key. /// The type of the value. public class MultiDictionary : IDictionary { #pragma warning disable CS8714 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint. private Dictionary> _Dictionary = null; #pragma warning restore CS8714 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint. /// /// Initializes a new instance of the class. /// public MultiDictionary() { #pragma warning disable CS8714 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint. _Dictionary = new Dictionary>(); #pragma warning restore CS8714 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint. } /// /// Adds an element with the provided key and value to the . /// /// The object to use as the key of the element to add. /// The object to use as the value of the element to add. /// is null. /// /// /// /// An element with the same key already exists in the . /// /// /// /// The is read-only. /// public void Add(TKey key, TValue value) { List list; if (_Dictionary.TryGetValue(key, out list)) { list.Add(value); } else { list = new List(); list.Add(value); _Dictionary.Add(key, list); } } /// /// Determines whether the contains an element with the specified key. /// /// The key to locate in the . /// /// true if the contains an element with the key; otherwise, false. /// /// is null. /// public bool ContainsKey(TKey key) { return _Dictionary.ContainsKey(key); } /// /// Removes the element with the specified key from the . /// /// The key of the element to remove. /// /// true if the element is successfully removed; otherwise, false. This method also returns false if was not found in the original . /// /// is null. /// /// /// /// The is read-only. /// public bool Remove(TKey key) { return _Dictionary.Remove(key); } /// /// Gets an containing the keys of the . /// /// /// An containing the keys of the object that implements . /// public ICollection Keys { get { return _Dictionary.Keys; } } /// /// Gets an containing the values in the . /// /// /// An containing the values in the object that implements . /// public ICollection Values { get { List values = new List(); #pragma warning disable CS8714 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint. using (Dictionary>.Enumerator enumerator = _Dictionary.GetEnumerator()) #pragma warning restore CS8714 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint. { while (enumerator.MoveNext()) { values.AddRange(enumerator.Current.Value); } } return values; } } bool IDictionary.TryGetValue(TKey key, out TValue value) { throw new NotSupportedException("TryGetValue is not supported"); } /// /// Gets or sets the element with the specified key. /// /// /// The element with the specified key. /// /// /// is null. /// /// /// /// The property is retrieved and is not found. /// /// /// /// The property is set and the is read-only. /// TValue IDictionary.this[TKey key] { get { return _Dictionary[key][0]; } set { _Dictionary[key][0] = value; } } /// /// Gets or sets the element with the specified key. /// /// /// The element with the specified key. /// /// /// is null. /// /// /// /// The property is retrieved and is not found. /// /// /// /// The property is set and the is read-only. /// public IList this[TKey key] { get { return _Dictionary[key]; } } /// /// Adds an item to the . /// /// The object to add to the . /// /// The is read-only. /// public void Add(KeyValuePair item) { Add(item.Key, item.Value); } /// /// Removes all items from the . /// /// /// The is read-only. /// public void Clear() { _Dictionary.Clear(); } /// /// Determines whether the contains a specific value. /// /// The object to locate in the . /// /// true if is found in the ; otherwise, false. /// public bool Contains(KeyValuePair item) { List list; if (!_Dictionary.TryGetValue(item.Key, out list)) { return false; } else { return list.Contains(item.Value); } } /// /// Copies to. /// /// The array. /// Index of the array. public void CopyTo(KeyValuePair[] array, int arrayIndex) { if (array == null) throw new ArgumentNullException("array"); if (arrayIndex < 0 || arrayIndex > array.Length) throw new ArgumentOutOfRangeException("array index out of range"); if (array.Length - arrayIndex < this.Count) throw new ArgumentException("Array too small"); Dictionary>.Enumerator enumerator = _Dictionary.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair> mapPair = enumerator.Current; foreach (TValue val in mapPair.Value) { array[arrayIndex++] = new KeyValuePair(mapPair.Key, val); } } } /// /// Gets the number of elements contained in the . /// /// /// The number of elements contained in the . /// public int Count { get { int count = 0; Dictionary>.Enumerator enumerator = _Dictionary.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair> pair = enumerator.Current; count += pair.Value.Count; } return count; } } /// /// Gets a value indicating whether the is read-only. /// /// true if the is read-only; otherwise, false. /// public bool IsReadOnly { get { return false; } } /// /// Removes the first occurrence of a specific object from the . /// /// The object to remove from the . /// /// true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . /// /// /// The is read-only. /// public bool Remove(KeyValuePair item) { List list; if (_Dictionary.TryGetValue(item.Key, out list)) { return list.Remove(item.Value); } else { return false; } } /// /// Returns an enumerator that iterates through the collection. /// /// /// A that can be used to iterate through the collection. /// public IEnumerator> GetEnumerator() { Dictionary>.Enumerator enumerateKeys = _Dictionary.GetEnumerator(); while (enumerateKeys.MoveNext()) { foreach (TValue val in enumerateKeys.Current.Value) { KeyValuePair pair = new KeyValuePair( enumerateKeys.Current.Key, val); yield return pair; } } } /// /// Returns an enumerator that iterates through a collection. /// /// /// An object that can be used to iterate through the collection. /// System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } } }