119 lines
3.4 KiB
C#
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();
|
|
}
|
|
}
|