c# - 从 ConditionalWeakTable<T> 获取事件项列表

标签 c# .net weak-references

.NET 4.0 ConditionalWeakTable<T>实际上是一个字典,其中字典的键被弱引用并且可以被收集,这正是我所需要的。问题是我需要能够从此字典中获取所有事件键,但是 MSDN states :

It does not include all the methods (such as GetEnumerator or Contains) that a dictionary typically has.

是否有可能从 ConditionalWeakTable<T> 中检索事件键或键值对? ?

最佳答案

我最终创建了自己的包装器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;

public sealed class ConditionalHashSet<T> where T : class
{
    private readonly object locker = new object();
    private readonly List<WeakReference> weakList = new List<WeakReference>();
    private readonly ConditionalWeakTable<T, WeakReference> weakDictionary =
        new ConditionalWeakTable<T, WeakReference>();

    public void Add(T item)
    {
        lock (this.locker)
        {
            var reference = new WeakReference(item);
            this.weakDictionary.Add(item, reference);
            this.weakList.Add(reference);
            this.Shrink();
        }
    }

    public void Remove(T item)
    {
        lock (this.locker)
        {
            WeakReference reference;

            if (this.weakDictionary.TryGetValue(item, out reference))
            {
                reference.Target = null;
                this.weakDictionary.Remove(item);
            }
        }
    }

    public T[] ToArray()
    {
        lock (this.locker)
        {
            return (
                from weakReference in this.weakList
                let item = (T)weakReference.Target
                where item != null
                select item)
                .ToArray();
        }
    }

    private void Shrink()
    {
        // This method prevents the List<T> from growing indefinitely, but 
        // might also cause  a performance problem in some cases.
        if (this.weakList.Capacity == this.weakList.Count)
        {
            this.weakList.RemoveAll(weak => !weak.IsAlive);
        }
    }
}

关于c# - 从 ConditionalWeakTable<T> 获取事件项列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18674325/

相关文章:

c# - 如何将 "stick"按钮移至 Telegram Bot 屏幕底部

.net - 为什么 "Non"中的 "ExecuteNonQuery"?

c# - 我可以用 throw 移除空捕获吗?

c# - 从 WebAPI 调用返回 Sitecore 媒体项目

c# - 匹配特定的打印机命令模式

c# - 将 Sharepoint 2007 解决方案转换为 2010

c# - 配置FluentNHibernate、FluentMappings.AddFromAssembly;意义

ruby - 在创建第二个对象之前不调用终结器,除非使用 weakref

c# - 检查.NET 3.5中对给定实例保留了多少引用