677 lines
22 KiB
C#
677 lines
22 KiB
C#
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Collections.Specialized;
|
|
using System.Linq;
|
|
|
|
namespace FlaxEngine.Collections
|
|
{
|
|
/// <summary>
|
|
/// A dictionary object that allows rapid hash lookups using keys, but also maintains the key insertion order so that values can be retrieved by key index.
|
|
/// </summary>
|
|
[Serializable]
|
|
public class OrderedDictionary<TKey, TValue> : IOrderedDictionary<TKey, TValue>
|
|
{
|
|
#region Fields/Properties
|
|
|
|
private KeyedCollectionInternal<TKey, KeyValuePair<TKey, TValue>> _keyedCollection;
|
|
|
|
/// <summary>
|
|
/// Gets or sets the value associated with the specified key.
|
|
/// </summary>
|
|
/// <param name="key">The key associated with the value to get or set.</param>
|
|
public TValue this[TKey key]
|
|
{
|
|
get => GetValue(key);
|
|
set => SetValue(key, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the value at the specified index.
|
|
/// </summary>
|
|
/// <param name="index">The index of the value to get or set.</param>
|
|
public TValue this[int index]
|
|
{
|
|
get => GetItem(index).Value;
|
|
set => SetItem(index, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the number of elements contained in the <see cref="OrderedDictionary{TKey,TValue}" />.
|
|
/// </summary>
|
|
/// <returns>The number of elements contained in the T:System.Collections.ICollection.</returns>
|
|
public int Count => _keyedCollection.Count;
|
|
|
|
/// <summary>
|
|
/// Gets an <see cref="T:System.Collections.ICollection" /> object containing the keys in the
|
|
/// <see cref="OrderedDictionary{TKey,TValue}" /> object.
|
|
/// </summary>
|
|
/// <returns>
|
|
/// An <see cref="T:System.Collections.ICollection" /> object containing the keys in the
|
|
/// <see cref="OrderedDictionary{TKey,TValue}" /> object.
|
|
/// </returns>
|
|
public ICollection<TKey> Keys
|
|
{
|
|
get { return _keyedCollection.Select(x => x.Key).ToList(); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets an <see cref="T:System.Collections.ICollection" /> object containing the values in the
|
|
/// <see cref="OrderedDictionary{TKey,TValue}" /> object.
|
|
/// </summary>
|
|
/// <returns>
|
|
/// An <see cref="T:System.Collections.ICollection" /> object containing the values in the
|
|
/// <see cref="OrderedDictionary{TKey,TValue}" /> object.
|
|
/// </returns>
|
|
public ICollection<TValue> Values
|
|
{
|
|
get { return _keyedCollection.Select(x => x.Value).ToList(); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The keys equality comparer.
|
|
/// </summary>
|
|
public IEqualityComparer<TKey> Comparer { get; private set; }
|
|
|
|
#endregion
|
|
|
|
#region Constructors
|
|
|
|
/// <summary>
|
|
/// A dictionary object that allows rapid hash lookups using keys, but also
|
|
/// maintains the key insertion order so that values can be retrieved by
|
|
/// key index.
|
|
/// </summary>
|
|
public OrderedDictionary()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// <inheritdoc cref="OrderedDictionary{TKey,TValue}" />
|
|
/// </summary>
|
|
/// <remarks>Allows custom comparer for items</remarks>
|
|
public OrderedDictionary(IEqualityComparer<TKey> comparer)
|
|
{
|
|
Initialize(comparer);
|
|
}
|
|
|
|
/// <summary>
|
|
/// <inheritdoc cref="OrderedDictionary{TKey,TValue}" />
|
|
/// </summary>
|
|
/// <remarks>Copy constructor</remarks>
|
|
public OrderedDictionary(IOrderedDictionary<TKey, TValue> dictionary)
|
|
{
|
|
Initialize();
|
|
foreach (KeyValuePair<TKey, TValue> pair in dictionary)
|
|
_keyedCollection.Add(pair);
|
|
}
|
|
|
|
/// <summary>
|
|
/// <inheritdoc cref="OrderedDictionary{TKey,TValue}" />
|
|
/// </summary>
|
|
/// <remarks>Copy constructor with custom items comparer</remarks>
|
|
public OrderedDictionary(IOrderedDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
|
|
{
|
|
Initialize(comparer);
|
|
foreach (KeyValuePair<TKey, TValue> pair in dictionary)
|
|
_keyedCollection.Add(pair);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
private void Initialize(IEqualityComparer<TKey> comparer = null)
|
|
{
|
|
Comparer = comparer;
|
|
if (comparer != null)
|
|
_keyedCollection = new KeyedCollectionInternal<TKey, KeyValuePair<TKey, TValue>>(x => x.Key, comparer);
|
|
else
|
|
_keyedCollection = new KeyedCollectionInternal<TKey, KeyValuePair<TKey, TValue>>(x => x.Key);
|
|
}
|
|
|
|
/// <summary>Adds an element with the specified key and value into the <see cref="OrderedDictionary{TKey,TValue}" />.</summary>
|
|
/// <param name="key">The key of the element to add.</param>
|
|
/// <param name="value">The value of the element to add.</param>
|
|
public void Add(TKey key, TValue value)
|
|
{
|
|
_keyedCollection.Add(new KeyValuePair<TKey, TValue>(key, value));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears the contents of the <see cref="OrderedDictionary{TKey,TValue}" /> instance.
|
|
/// </summary>
|
|
public void Clear()
|
|
{
|
|
_keyedCollection.Clear();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Performs additional custom processes before inserting a new element into the
|
|
/// <see cref="OrderedDictionary{TKey,TValue}" /> instance.
|
|
/// </summary>
|
|
/// <param name="index">The index.</param>
|
|
/// <param name="key">The key of the element to insert.</param>
|
|
/// <param name="value">The value of the element to insert.</param>
|
|
public void Insert(int index, TKey key, TValue value)
|
|
{
|
|
_keyedCollection.Insert(index, new KeyValuePair<TKey, TValue>(key, value));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether an element is in the <see cref="OrderedDictionary{TKey,TValue}" />.
|
|
/// </summary>
|
|
/// <param name="key">The object to locate in the current dictionary. The element to locate can be null for reference types.</param>
|
|
/// <returns>The index of the item.</returns>
|
|
public int IndexOf(TKey key)
|
|
{
|
|
if (_keyedCollection.Contains(key))
|
|
return _keyedCollection.IndexOf(_keyedCollection[key]);
|
|
return -1;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether the <see cref="OrderedDictionary{TKey,TValue}" /> contains a specific value.
|
|
/// </summary>
|
|
/// <param name="value">The value to locate in the <see cref="OrderedDictionary{TKey,TValue}" />.</param>
|
|
/// <returns>True if the <see cref="OrderedDictionary{TKey,TValue}" /> contains an element with the specified value; otherwise, false.</returns>
|
|
public bool ContainsValue(TValue value)
|
|
{
|
|
return Values.Contains(value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether the <see cref="OrderedDictionary{TKey,TValue}" /> contains a specific value.
|
|
/// </summary>
|
|
/// <param name="value">The value to locate in the <see cref="OrderedDictionary{TKey,TValue}" />.</param>
|
|
/// <param name="comparer">The custom <see cref="IEqualityComparer" /> for this search</param>
|
|
/// <returns>True if the <see cref="OrderedDictionary{TKey,TValue}" /> contains an element with the specified value; otherwise, false.</returns>
|
|
public bool ContainsValue(TValue value, IEqualityComparer<TValue> comparer)
|
|
{
|
|
return Values.Contains(value, comparer);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether the <see cref="OrderedDictionary{TKey,TValue}" /> contains a specific key.
|
|
/// </summary>
|
|
/// <param name="key">The key to locate in the <see cref="OrderedDictionary{TKey,TValue}" />.</param>
|
|
/// <returns>True if the <see cref="OrderedDictionary{TKey,TValue}" /> contains an element with the specified key; otherwise, false.</returns>
|
|
public bool ContainsKey(TKey key)
|
|
{
|
|
return _keyedCollection.Contains(key);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets item at given index.
|
|
/// </summary>
|
|
/// <param name="index">Requested key at index</param>
|
|
/// <exception cref="ArgumentException">
|
|
/// Thrown when the index specified does not refer to a KeyValuePair in this object
|
|
/// </exception>
|
|
public KeyValuePair<TKey, TValue> GetItem(int index)
|
|
{
|
|
if (index < 0 || index >= _keyedCollection.Count)
|
|
throw new ArgumentException(string.Format("The index was outside the bounds of the dictionary: {0}", index));
|
|
return _keyedCollection[index];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the value at the index specified.
|
|
/// </summary>
|
|
/// <param name="index">The index of the value desired</param>
|
|
/// <param name="value">The value to set</param>
|
|
/// <exception cref="ArgumentOutOfRangeException">
|
|
/// Thrown when the index specified does not refer to a KeyValuePair in this object
|
|
/// </exception>
|
|
public void SetItem(int index, TValue value)
|
|
{
|
|
if (index < 0 || index >= _keyedCollection.Count)
|
|
throw new ArgumentException($"The index is outside the bounds of the dictionary: {index}");
|
|
var kvp = new KeyValuePair<TKey, TValue>(_keyedCollection[index].Key, value);
|
|
_keyedCollection[index] = kvp;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns an <see cref="T:System.Collections.IEnumerator" /> that iterates through the
|
|
/// <see cref="OrderedDictionary{TKey,TValue}" />.
|
|
/// </summary>
|
|
/// <returns>An <see cref="T:System.Collections.IEnumerator" /> for the <see cref="OrderedDictionary{TKey,TValue}" />.</returns>
|
|
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
|
|
{
|
|
return _keyedCollection.GetEnumerator();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Performs additional custom processes before removing an element from the
|
|
/// <see cref="OrderedDictionary{TKey,TValue}" /> instance.
|
|
/// </summary>
|
|
/// <param name="key">The key of the element to remove.</param>
|
|
public bool Remove(TKey key)
|
|
{
|
|
return _keyedCollection.Remove(key);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes the <see cref="OrderedDictionary{TKey,TValue}" /> item at the specified index.
|
|
/// </summary>
|
|
/// <param name="index">The zero-based index of the item to remove.</param>
|
|
public void RemoveAt(int index)
|
|
{
|
|
if (index < 0 || index >= _keyedCollection.Count)
|
|
throw new ArgumentException($"The index was outside the bounds of the dictionary: {index}");
|
|
_keyedCollection.RemoveAt(index);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the value associated with the specified key.
|
|
/// </summary>
|
|
/// <param name="key">The key associated with the value to get.</param>
|
|
public TValue GetValue(TKey key)
|
|
{
|
|
if (_keyedCollection.Contains(key) == false)
|
|
throw new ArgumentException($"The given key is not present in the dictionary: {key}");
|
|
var kvp = _keyedCollection[key];
|
|
return kvp.Value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the value associated with the specified key.
|
|
/// </summary>
|
|
/// <param name="key">The key associated with the value to set.</param>
|
|
/// <param name="value">The the value to set.</param>
|
|
public void SetValue(TKey key, TValue value)
|
|
{
|
|
var kvp = new KeyValuePair<TKey, TValue>(key, value);
|
|
var idx = IndexOf(key);
|
|
if (idx > -1)
|
|
_keyedCollection[idx] = kvp;
|
|
else
|
|
_keyedCollection.Add(kvp);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to get value at specified key.
|
|
/// </summary>
|
|
/// <param name="key">The key associated with the value to find.</param>
|
|
/// <param name="value">Found value.</param>
|
|
/// <returns>true if value existed, false if not</returns>
|
|
public bool TryGetValue(TKey key, out TValue value)
|
|
{
|
|
if (_keyedCollection.Contains(key))
|
|
{
|
|
value = _keyedCollection[key].Value;
|
|
return true;
|
|
}
|
|
|
|
value = default;
|
|
return false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Sorting
|
|
|
|
/// <summary>
|
|
/// Sorts the keys.
|
|
/// </summary>
|
|
public void SortKeys()
|
|
{
|
|
_keyedCollection.SortByKeys();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sorts the keys.
|
|
/// </summary>
|
|
/// <param name="comparer">The comparer.</param>
|
|
public void SortKeys(IComparer<TKey> comparer)
|
|
{
|
|
_keyedCollection.SortByKeys(comparer);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sorts the keys.
|
|
/// </summary>
|
|
/// <param name="comparison">The comparison.</param>
|
|
public void SortKeys(Comparison<TKey> comparison)
|
|
{
|
|
_keyedCollection.SortByKeys(comparison);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sorts the values.
|
|
/// </summary>
|
|
public void SortValues()
|
|
{
|
|
var comparer = Comparer<TValue>.Default;
|
|
SortValues(comparer);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sorts the values.
|
|
/// </summary>
|
|
/// <param name="comparer">The comparer.</param>
|
|
public void SortValues(IComparer<TValue> comparer)
|
|
{
|
|
_keyedCollection.Sort((x, y) => comparer.Compare(x.Value, y.Value));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sorts the values.
|
|
/// </summary>
|
|
/// <param name="comparison">The comparison.</param>
|
|
public void SortValues(Comparison<TValue> comparison)
|
|
{
|
|
_keyedCollection.Sort((x, y) => comparison(x.Value, y.Value));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IDictionary<TKey, TValue>
|
|
|
|
void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
|
|
{
|
|
Add(key, value);
|
|
}
|
|
|
|
bool IDictionary<TKey, TValue>.ContainsKey(TKey key)
|
|
{
|
|
return ContainsKey(key);
|
|
}
|
|
|
|
ICollection<TKey> IDictionary<TKey, TValue>.Keys => Keys;
|
|
|
|
bool IDictionary<TKey, TValue>.Remove(TKey key)
|
|
{
|
|
return Remove(key);
|
|
}
|
|
|
|
bool IDictionary<TKey, TValue>.TryGetValue(TKey key, out TValue value)
|
|
{
|
|
return TryGetValue(key, out value);
|
|
}
|
|
|
|
ICollection<TValue> IDictionary<TKey, TValue>.Values => Values;
|
|
|
|
TValue IDictionary<TKey, TValue>.this[TKey key]
|
|
{
|
|
get => this[key];
|
|
set => this[key] = value;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ICollection<KeyValuePair<TKey, TValue>>
|
|
|
|
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
|
|
{
|
|
_keyedCollection.Add(item);
|
|
}
|
|
|
|
void ICollection<KeyValuePair<TKey, TValue>>.Clear()
|
|
{
|
|
_keyedCollection.Clear();
|
|
}
|
|
|
|
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
|
|
{
|
|
return _keyedCollection.Contains(item);
|
|
}
|
|
|
|
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
|
|
{
|
|
_keyedCollection.CopyTo(array, arrayIndex);
|
|
}
|
|
|
|
int ICollection<KeyValuePair<TKey, TValue>>.Count => _keyedCollection.Count;
|
|
|
|
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => false;
|
|
|
|
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
|
|
{
|
|
return _keyedCollection.Remove(item);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IEnumerable<KeyValuePair<TKey, TValue>>
|
|
|
|
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IEnumerable
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IOrderedDictionary
|
|
|
|
IDictionaryEnumerator IOrderedDictionary.GetEnumerator()
|
|
{
|
|
return new DictionaryEnumerator<TKey, TValue>(this);
|
|
}
|
|
|
|
void IOrderedDictionary.Insert(int index, object key, object value)
|
|
{
|
|
Insert(index, (TKey)key, (TValue)value);
|
|
}
|
|
|
|
void IOrderedDictionary.RemoveAt(int index)
|
|
{
|
|
RemoveAt(index);
|
|
}
|
|
|
|
object IOrderedDictionary.this[int index]
|
|
{
|
|
get => this[index];
|
|
set => this[index] = (TValue)value;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IDictionary
|
|
|
|
void IDictionary.Add(object key, object value)
|
|
{
|
|
Add((TKey)key, (TValue)value);
|
|
}
|
|
|
|
void IDictionary.Clear()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
bool IDictionary.Contains(object key)
|
|
{
|
|
return _keyedCollection.Contains((TKey)key);
|
|
}
|
|
|
|
IDictionaryEnumerator IDictionary.GetEnumerator()
|
|
{
|
|
return new DictionaryEnumerator<TKey, TValue>(this);
|
|
}
|
|
|
|
bool IDictionary.IsFixedSize => false;
|
|
|
|
bool IDictionary.IsReadOnly => false;
|
|
|
|
ICollection IDictionary.Keys => (ICollection)Keys;
|
|
|
|
void IDictionary.Remove(object key)
|
|
{
|
|
Remove((TKey)key);
|
|
}
|
|
|
|
ICollection IDictionary.Values => (ICollection)Values;
|
|
|
|
object IDictionary.this[object key]
|
|
{
|
|
get => this[(TKey)key];
|
|
set => this[(TKey)key] = (TValue)value;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ICollection
|
|
|
|
void ICollection.CopyTo(Array array, int index)
|
|
{
|
|
((ICollection)_keyedCollection).CopyTo(array, index);
|
|
}
|
|
|
|
int ICollection.Count => ((ICollection)_keyedCollection).Count;
|
|
|
|
bool ICollection.IsSynchronized => ((ICollection)_keyedCollection).IsSynchronized;
|
|
|
|
object ICollection.SyncRoot => ((ICollection)_keyedCollection).SyncRoot;
|
|
|
|
#endregion
|
|
}
|
|
|
|
[Serializable]
|
|
internal class KeyedCollectionInternal<TKey, TItem> : KeyedCollection<TKey, TItem>
|
|
{
|
|
private const string DelegateNullExceptionMessage = "Delegate passed cannot be null";
|
|
private Func<TItem, TKey> _getKeyForItemDelegate;
|
|
|
|
public KeyedCollectionInternal(Func<TItem, TKey> getKeyForItemDelegate)
|
|
{
|
|
_getKeyForItemDelegate = getKeyForItemDelegate ?? throw new ArgumentNullException(DelegateNullExceptionMessage);
|
|
}
|
|
|
|
public KeyedCollectionInternal(Func<TItem, TKey> getKeyForItemDelegate, IEqualityComparer<TKey> comparer)
|
|
: base(comparer)
|
|
{
|
|
_getKeyForItemDelegate = getKeyForItemDelegate ?? throw new ArgumentNullException(DelegateNullExceptionMessage);
|
|
}
|
|
|
|
protected override TKey GetKeyForItem(TItem item)
|
|
{
|
|
return _getKeyForItemDelegate(item);
|
|
}
|
|
|
|
public void SortByKeys()
|
|
{
|
|
var comparer = Comparer<TKey>.Default;
|
|
SortByKeys(comparer);
|
|
}
|
|
|
|
public void SortByKeys(IComparer<TKey> keyComparer)
|
|
{
|
|
var comparer = new ComparerInternal<TItem>((x, y) => keyComparer.Compare(GetKeyForItem(x), GetKeyForItem(y)));
|
|
Sort(comparer);
|
|
}
|
|
|
|
public void SortByKeys(Comparison<TKey> keyComparison)
|
|
{
|
|
var comparer = new ComparerInternal<TItem>((x, y) => keyComparison(GetKeyForItem(x), GetKeyForItem(y)));
|
|
Sort(comparer);
|
|
}
|
|
|
|
public void Sort()
|
|
{
|
|
var comparer = Comparer<TItem>.Default;
|
|
Sort(comparer);
|
|
}
|
|
|
|
public void Sort(Comparison<TItem> comparison)
|
|
{
|
|
var newComparer = new ComparerInternal<TItem>(comparison);
|
|
Sort(newComparer);
|
|
}
|
|
|
|
public void Sort(IComparer<TItem> comparer)
|
|
{
|
|
if (Items is List<TItem> list)
|
|
list.Sort(comparer);
|
|
}
|
|
}
|
|
|
|
internal class ComparerInternal<T> : Comparer<T>
|
|
{
|
|
private readonly Comparison<T> _compareFunction;
|
|
|
|
/// <inheritdoc />
|
|
public ComparerInternal(Comparison<T> comparison)
|
|
{
|
|
_compareFunction = comparison ?? throw new ArgumentNullException(nameof(comparison));
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override int Compare(T arg1, T arg2)
|
|
{
|
|
return _compareFunction(arg1, arg2);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The enumerator implementation for dictionary
|
|
/// </summary>
|
|
/// <typeparam name="TKey">The type of the key.</typeparam>
|
|
/// <typeparam name="TValue">The type of the value.</typeparam>
|
|
/// <seealso cref="System.Collections.IDictionaryEnumerator" />
|
|
/// <seealso cref="System.IDisposable" />
|
|
[Serializable]
|
|
public class DictionaryEnumerator<TKey, TValue> : IDictionaryEnumerator, IDisposable
|
|
{
|
|
private readonly IEnumerator<KeyValuePair<TKey, TValue>> _impl;
|
|
|
|
/// <inheritdoc />
|
|
public void Dispose()
|
|
{
|
|
_impl.Dispose();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="DictionaryEnumerator{TKey, TValue}"/> class.
|
|
/// </summary>
|
|
/// <param name="value">The value.</param>
|
|
public DictionaryEnumerator(IDictionary<TKey, TValue> value)
|
|
{
|
|
_impl = value.GetEnumerator();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void Reset()
|
|
{
|
|
_impl.Reset();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool MoveNext()
|
|
{
|
|
return _impl.MoveNext();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public DictionaryEntry Entry
|
|
{
|
|
get
|
|
{
|
|
var pair = _impl.Current;
|
|
return new DictionaryEntry(pair.Key, pair.Value);
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public object Key => _impl.Current.Key;
|
|
|
|
/// <inheritdoc />
|
|
public object Value => _impl.Current.Value;
|
|
|
|
/// <inheritdoc />
|
|
public object Current => Entry;
|
|
}
|
|
}
|