ln.collections/ln.collections/WeakValueDictionary.cs

119 lines
3.4 KiB
C#

// /**
// * 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<K,V> : IDictionary<K,V> where V:class
{
Dictionary<K, WeakReference<V>> keyValues = new Dictionary<K, WeakReference<V>>();
public WeakValueDictionary()
{
}
public V this[K key] {
get => TryGetValue(key, out V value) ? value : throw new KeyNotFoundException();
set => SetValue(key, value);
}
public ICollection<K> Keys => keyValues.Keys;
public ICollection<V> Values
{
get
{
List<V> values = new List<V>();
foreach (K key in Keys.ToArray())
{
WeakReference<V> 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<K, V> 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<K, V> 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<K, V>[] array, int arrayIndex)
{
foreach (KeyValuePair<K,WeakReference<V>> kvp in keyValues)
{
if (kvp.Value.TryGetTarget(out V value))
array[arrayIndex++] = new KeyValuePair<K, V>(kvp.Key, value);
}
}
public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
{
foreach (KeyValuePair<K, WeakReference<V>> kvp in keyValues)
{
if (kvp.Value.TryGetTarget(out V value))
yield return new KeyValuePair<K, V>(kvp.Key, value);
}
}
public bool Remove(K key) => keyValues.Remove(key);
public bool Remove(KeyValuePair<K, V> item) => Remove(item.Key);
public bool TryGetValue(K key, out V value)
{
if (keyValues.TryGetValue(key, out WeakReference<V> 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<V>(value);
return true;
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
}