AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/InputDevicesManager/DualWayDictionary.cs

133 lines
4.8 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
namespace AxibugEmuOnline.Client.InputDevices
{
/// <summary>
/// 双向字典
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
public class DualWayDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary
where TKey : notnull
where TValue : notnull
{
private readonly Dictionary<TKey, TValue> _forward = new();
private readonly Dictionary<TValue, TKey> _reverse = new();
// 显式实现非泛型接口
bool IDictionary.IsFixedSize => false;
bool IDictionary.IsReadOnly => false;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => ((ICollection)_forward).SyncRoot;
// 泛型接口实现
public TValue this[TKey key]
{
get => _forward[key];
set
{
if (_forward.TryGetValue(key, out var oldValue))
_reverse.Remove(oldValue);
_forward[key] = value;
_reverse[value] = key;
}
}
object? IDictionary.this[object key]
{
get => key is TKey k ? _forward[k] : null;
set
{
if (key is TKey tk && value is TValue tv)
this[tk] = tv;
}
}
public ICollection<TKey> Keys => _forward.Keys;
public ICollection<TValue> Values => _forward.Values;
ICollection IDictionary.Keys => _forward.Keys;
ICollection IDictionary.Values => _forward.Values;
public int Count => _forward.Count;
public bool IsReadOnly => false;
// 双向查询扩展
public bool TryGetKey(TValue value, out TKey key) => _reverse.TryGetValue(value, out key);
public bool TryGetValue(TKey key, out TValue value) => _forward.TryGetValue(key, out value);
// 接口方法实现
public void Add(TKey key, TValue value)
{
if (_forward.ContainsKey(key) || _reverse.ContainsKey(value))
throw new ArgumentException("键或值已存在");
_forward.Add(key, value);
_reverse.Add(value, key);
}
public void Add(KeyValuePair<TKey, TValue> item) => Add(item.Key, item.Value);
void IDictionary.Add(object key, object value)
{
if (key is TKey k && value is TValue v)
Add(k, v);
else
throw new ArgumentException("类型不匹配");
}
public bool Contains(object key) => key is TKey k && _forward.ContainsKey(k);
public bool Contains(KeyValuePair<TKey, TValue> item) => _forward.TryGetValue(item.Key, out var v) && v.Equals(item.Value);
public bool ContainsKey(TKey key) => _forward.ContainsKey(key);
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
((ICollection<KeyValuePair<TKey, TValue>>)_forward).CopyTo(array, arrayIndex);
}
public void CopyTo(Array array, int index)
{
((ICollection)_forward).CopyTo(array, index);
}
public bool Remove(TKey key)
{
if (!_forward.Remove(key, out var value)) return false;
_reverse.Remove(value);
return true;
}
public bool Remove(KeyValuePair<TKey, TValue> item) => Remove(item.Key);
void IDictionary.Remove(object key)
{
if (key is TKey k) Remove(k);
}
public void Clear()
{
_forward.Clear();
_reverse.Clear();
}
// 枚举器实现
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => _forward.GetEnumerator();
IDictionaryEnumerator IDictionary.GetEnumerator() => new DictionaryEnumerator(_forward.GetEnumerator());
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
// 非泛型枚举器适配器
private class DictionaryEnumerator : IDictionaryEnumerator
{
private readonly IEnumerator<KeyValuePair<TKey, TValue>> _enumerator;
public DictionaryEnumerator(IEnumerator<KeyValuePair<TKey, TValue>> enumerator) => _enumerator = enumerator;
public DictionaryEntry Entry => new(_enumerator.Current.Key, _enumerator.Current.Value);
public object Key => _enumerator.Current.Key;
public object? Value => _enumerator.Current.Value;
public object Current => Entry;
public bool MoveNext() => _enumerator.MoveNext();
public void Reset() => _enumerator.Reset();
}
}
}