ObjectDictionary.cs

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