// /** // * File: WeakValueDictionary.cs // * Author: haraldwolff // * // * This file and it's content is copyrighted by the Author and / or copyright holder. // * Any use wihtout proper permission is illegal and may lead to legal actions. // * // * // **/ using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace ln.collections { public class WeakValueDictionary : IDictionary where V:class { Dictionary> keyValues = new Dictionary>(); public WeakValueDictionary() { } public V this[K key] { get => TryGetValue(key, out V value) ? value : throw new KeyNotFoundException(); set => SetValue(key, value); } public ICollection Keys => keyValues.Keys; public ICollection Values { get { List values = new List(); foreach (K key in Keys.ToArray()) { WeakReference weakValue = keyValues[key]; if (weakValue.TryGetTarget(out V value)) { values.Add(value); } else { keyValues.Remove(key); } } return values; } } public int Count => keyValues.Count; public bool IsReadOnly => false; public void Add(KeyValuePair item) => Add(item.Key, item.Value); public void Add(K key, V value) { if (keyValues.ContainsKey(key)) throw new ArgumentException(); SetValue(key, value); } public void Clear() => keyValues.Clear(); public bool Contains(KeyValuePair item) { if (TryGetValue(item.Key,out V value)) { return Equals(item.Value, value); } return false; } public bool ContainsKey(K key) => keyValues.ContainsKey(key); public void CopyTo(KeyValuePair[] array, int arrayIndex) { foreach (KeyValuePair> kvp in keyValues) { if (kvp.Value.TryGetTarget(out V value)) array[arrayIndex++] = new KeyValuePair(kvp.Key, value); } } public IEnumerator> GetEnumerator() { foreach (KeyValuePair> kvp in keyValues) { if (kvp.Value.TryGetTarget(out V value)) yield return new KeyValuePair(kvp.Key, value); } } public bool Remove(K key) => keyValues.Remove(key); public bool Remove(KeyValuePair item) => Remove(item.Key); public bool TryGetValue(K key, out V value) { if (keyValues.TryGetValue(key, out WeakReference weakValue)) { if (weakValue.TryGetTarget(out value)) return true; keyValues.Remove(key); } value = null; return false; } public bool SetValue(K key,V value) { keyValues[key] = new WeakReference(value); return true; } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } }