Object Dictionary Single Associative Array, Searchable Keys and Values
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; [DebuggerDisplay("Count = {Count}")] [Serializable] public class ObjectDictionary : MonitorActionFuncWrapper, IEnumerable<KeyValuePair<object, object>> { public ObjectBase _keys; public ObjectBase _values; public ObjectDictionary() : this(101) { } public ObjectDictionary(int size) { _keys = new ObjectBase(size); _values = new ObjectBase(size); } public ObjectDictionary(IEnumerable<KeyValuePair<object, object>> collection) { foreach (var kp in collection) Add(kp.Key, kp.Value); } public int Count => _keys.Count; public object this[object key] { get { var pos = _keys.GetObjectIndex(key, false); return pos.idx == -1 ? default : _values[pos.idx]; } set => Add(key, value); } public object[] Values => _values.ToArray(); public KeyValuePair<object, object>[] KeyValuePairs => ToArray(); public object[] Keys => _keys.ToArray(); public IEnumerator<KeyValuePair<object, object>> GetEnumerator() { return Lock(this, () => { return GetEnum(); }); } IEnumerator IEnumerable.GetEnumerator() { return Lock(this, () => { return GetEnum(); }); } private IEnumerator<KeyValuePair<object, object>> GetEnum() { for (var i = 0; i < Count; i++) yield return new KeyValuePair<object, object>(_keys[i], _values[i]); } public bool Add(object key, object value) { return Lock(this, () => { if (_keys.Contains(key) || _values.Contains(value)) return false; var ka = _keys.Add(key); var va = _values.Add(value); if (ka || va) { int a = 1; } return ka && va; }); } public void RemoveKey(object key) { var kidx = _keys.GetObjectIndex(key, false).idx; if (kidx != -1) { var keys = _keys; var values = _values; Clear(); for (var i = 0; i < keys.Count; ++i) if (i != kidx) Add(keys[i], values[i]); } } public void RemoveValue(object value) { var vidx = _values.GetObjectIndex(value, false).idx; if (vidx != -1) { var keys = _keys; var values = _values; Clear(); for (var i = 0; i < keys.Count; ++i) if (i != vidx) Add(keys[i], values[i]); } } public void RebuildLists() { var keys = _keys; var values = _values; Clear(); for (var i = 0; i < keys.Count; ++i) Add(keys[i], values[i]); } public bool ContainsKey(object key) { return Lock(this, () => { return _keys.Contains(key); }); } public bool ContainsValue(object value) { return Lock(this, () => { return _values.Contains(value); }); } public int FindKeyIndex(object key) { return Lock(this, () => { return _keys.GetObjectIndex(key, false).idx; }); } public int FindValueIndex(object value) { return Lock(this, () => { return _values.GetObjectIndex(value, false).idx; }); } public KeyValuePair<object, object>[] ToArray() { return Lock(this, () => { var array = new KeyValuePair<object, object>[Count]; for (var i = 0; i < Count; i++) array[i] = new KeyValuePair<object, object>(_keys[i], _values[i]); return array; }); } public void Clear() { Lock(this, () => { _keys = new ObjectBase(_keys.Count); _values = new ObjectBase(_values.Count); }); } }