committed by
GitHub
3 changed files with 146 additions and 1 deletions
@ -0,0 +1,144 @@ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Avalonia.Utilities |
|||
{ |
|||
/// <summary>
|
|||
/// Stores either a single key value pair or constructs a dictionary when more than one value is stored.
|
|||
/// </summary>
|
|||
/// <typeparam name="TKey">The type of the key.</typeparam>
|
|||
/// <typeparam name="TValue">The type of the value.</typeparam>
|
|||
public class SingleOrDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>> |
|||
{ |
|||
private KeyValuePair<TKey, TValue>? _singleValue; |
|||
private Dictionary<TKey, TValue> dictionary; |
|||
|
|||
public void Add(TKey key, TValue value) |
|||
{ |
|||
if (_singleValue != null) |
|||
{ |
|||
dictionary = new Dictionary<TKey, TValue>(); |
|||
((ICollection<KeyValuePair<TKey, TValue>>)dictionary).Add(_singleValue.Value); |
|||
_singleValue = null; |
|||
} |
|||
|
|||
if (dictionary != null) |
|||
{ |
|||
dictionary.Add(key, value); |
|||
} |
|||
else |
|||
{ |
|||
_singleValue = new KeyValuePair<TKey, TValue>(key, value); |
|||
} |
|||
} |
|||
|
|||
public bool TryGetValue(TKey key, out TValue value) |
|||
{ |
|||
if (dictionary == null) |
|||
{ |
|||
if (!_singleValue.HasValue || !_singleValue.Value.Key.Equals(key)) |
|||
{ |
|||
value = default(TValue); |
|||
return false; |
|||
} |
|||
else |
|||
{ |
|||
value = _singleValue.Value.Value; |
|||
return true; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
return dictionary.TryGetValue(key, out value); |
|||
} |
|||
} |
|||
|
|||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() |
|||
{ |
|||
if (dictionary == null) |
|||
{ |
|||
if (_singleValue.HasValue) |
|||
{ |
|||
return new SingleEnumerator<KeyValuePair<TKey, TValue>>(_singleValue.Value); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
return dictionary.GetEnumerator(); |
|||
} |
|||
return Enumerable.Empty<KeyValuePair<TKey, TValue>>().GetEnumerator(); |
|||
} |
|||
|
|||
IEnumerator IEnumerable.GetEnumerator() |
|||
{ |
|||
return GetEnumerator(); |
|||
} |
|||
|
|||
public IEnumerable<TValue> Values |
|||
{ |
|||
get |
|||
{ |
|||
if(dictionary == null) |
|||
{ |
|||
if (_singleValue.HasValue) |
|||
{ |
|||
return new[] { _singleValue.Value.Value }; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
return dictionary.Values; |
|||
} |
|||
return Enumerable.Empty<TValue>(); |
|||
} |
|||
} |
|||
|
|||
private class SingleEnumerator<T> : IEnumerator<T> |
|||
{ |
|||
private T value; |
|||
private int index = -1; |
|||
|
|||
public SingleEnumerator(T value) |
|||
{ |
|||
this.value = value; |
|||
} |
|||
|
|||
public T Current |
|||
{ |
|||
get |
|||
{ |
|||
if (index == 0) |
|||
{ |
|||
return value; |
|||
} |
|||
else |
|||
{ |
|||
throw new InvalidOperationException(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
object IEnumerator.Current => Current; |
|||
|
|||
public void Dispose() |
|||
{ |
|||
} |
|||
|
|||
public bool MoveNext() |
|||
{ |
|||
index++; |
|||
return index < 1; |
|||
} |
|||
|
|||
public void Reset() |
|||
{ |
|||
index = -1; |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
Loading…
Reference in new issue