Created
March 16, 2018 23:28
-
-
Save JohnLBevan/eaa313821bb54ef545ed3b764fa6f599 to your computer and use it in GitHub Desktop.
Bidirectional generic dictionary; used for simple 1:1 mappings. Just holds 2 dictionaries 1 key,value the other value,key. Probably a better solution exists, but this meets my needs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections; | |
| using System.Collections.Generic; | |
| namespace JohnLBevan.Collections.Generic | |
| { | |
| public class BidirectionalDictionary<T1, T2>: IDictionary<T1, T2> | |
| { | |
| IDictionary<T1, T2> ab; | |
| IDictionary<T2, T1> ba; | |
| public BidirectionalDictionary() | |
| { | |
| ab = new Dictionary<T1, T2>(); | |
| ba = new Dictionary<T2, T1>(); | |
| } | |
| public void Add(T1 key, T2 value) | |
| { | |
| AssertNotInDictionary(key, value); | |
| ab.Add(key, value); | |
| ba.Add(value, key); | |
| } | |
| public T2 this[T1 key] | |
| { | |
| get => ab[key]; | |
| set { | |
| AssertNotInDictionary(key, value); | |
| ab[key] = value; | |
| ba[value] = key; | |
| } | |
| } | |
| public ICollection<T1> Keys => ab.Keys; | |
| public ICollection<T2> Values => ab.Values; | |
| public int Count => ab.Count; | |
| public bool IsReadOnly => ab.IsReadOnly; | |
| public void Add(KeyValuePair<T1, T2> item) => Add(item.Key, item.Value); | |
| public void Clear() | |
| { | |
| ab.Clear(); | |
| ba.Clear(); | |
| } | |
| public bool Contains(KeyValuePair<T1, T2> item) => ab.Contains(item); | |
| public bool ContainsKey(T1 key) => ab.ContainsKey(key); | |
| public bool ContainsValue(T2 value) => ba.ContainsKey(value); | |
| public void CopyTo(KeyValuePair<T1, T2>[] array, int arrayIndex) => ab.CopyTo(array, arrayIndex); | |
| public IEnumerator<KeyValuePair<T1, T2>> GetEnumerator() => ab.GetEnumerator(); | |
| public bool Remove(T1 key) | |
| { | |
| ab.TryGetValue(key, out T2 value); | |
| return ab.Remove(key) && ba.Remove(value); | |
| } | |
| public bool Remove2(T2 key) | |
| { | |
| ba.TryGetValue(key, out T1 value); | |
| return ba.Remove(key) && ab.Remove(value); | |
| } | |
| public bool Remove(KeyValuePair<T1, T2> item) => ab.Remove(item) && ba.Remove(item.Value); | |
| public bool TryGetValue(T1 key, out T2 value) => ab.TryGetValue(key, out value); | |
| public bool TryGetValue2(T2 key, out T1 value) => ba.TryGetValue(key, out value); | |
| IEnumerator IEnumerable.GetEnumerator() => ab.GetEnumerator(); | |
| const string ElementAlreadyExistsExceptionMessage = "An element with the same key already exists. {0}"; | |
| const string ParameterNameKey = "key"; | |
| const string ParameterNameValue = "value"; | |
| private void AssertNotInDictionary(T1 key, T2 value) | |
| { | |
| if (ab.ContainsKey(key)) throw new ArgumentException(string.Format(ElementAlreadyExistsExceptionMessage,key), ParameterNameKey); | |
| if (ba.ContainsKey(value)) throw new ArgumentException(string.Format(ElementAlreadyExistsExceptionMessage,value), ParameterNameValue); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment