在.Net中实现弱字典

Kon*_*rin 30 .net dictionary weak-references

我在哪里可以找到IDictionary使用弱引用的良好实现?

字典应该只保留对值的弱引用,并最终清除死引用本身.

或者我应该自己写吗?

mad*_*ang 29

ConditionalWeakTable类使用弱键,并在表外没有其他对键的引用时自动删除键/值条目.

  • OP要求弱字典**弱字典**..NET`ConditionalWeakTable`类是弱字典**弱字典**.因此,我不相信这是一个正确的答案. (19认同)
  • 应该注意的是,这个类使用`ReferenceEquals`而不是`GetHashCode`和`Equals`来进行相等性检查.有关更全面的讨论,请参见http://stackoverflow.com/a/8441180/167251. (3认同)
  • 但这正是我正在寻找的:P所以感谢确认这一点! (3认同)

Pau*_*der 5

你需要自己写.它应该相对简单,实现IDictionary接口,然后将实际值存储为WeakReferences.然后,您可以检查添加/选择的值,看看它们是否仍然存在.

伪代码 - 不会真正编译:

public class WeakDictionary <TKey,TValue> : IDictionary<TKey,TValue>
{
    private IDictionary<TKey,WeakReference> _innerDictionary = new Dictionary<TKey,WeakReference>();


    public TValue Index[ TKey key ]
    {
        get{
            var reference = _innerDictionary[ key ];
            if( reference.IsAlive )
                return (TValue)reference.Target;
            throw new InvalidOperation( "Key not found." );
        }

    }

    private void Cull()
    {
        var deadKeys = new List<TKey>();
        foreach( var pair in _innerDictionary )
        {
            if( ! pair.Value.IsAlive )
                deadKeys.Add( pair.Key );
        }

        foreach( var key in deadKeys )
            _innerDictionary.Remove( key );
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 要小心,在`reference.IsAlive`和`reference.Target`之间可能会发生垃圾收集,从而使这个解决方案容易出现竞争条件. (10认同)
  • 是的,就像其他人建议的那样,使用 TryGetTarget 和 WeakReference&lt;T&gt; (3认同)
  • 在检查修复该比赛的 IsAlive 之前,将 Target 放在您自己的堆栈上很容易 (2认同)
  • 你为什么不使用WeakReference.TryGetValue? (2认同)