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();
}
}
}