ConditionalWeakTable 是 .NET 中线程安全、弱引用的键值映射结构,专用于为对象临时附加数据且不阻止其被 GC 回收,适用于 AOP、序列化上下文、调试信息挂载等场景。

ConditionalWeakTable 是什么,适合解决什么问题
ConditionalWeakTable 是 .NET 提供的一个线程安全、弱引用的键值映射结构,核心用途是「把额外数据临时挂载到某个对象实例上」,且不阻止该对象被 GC 回收。它不是通用字典,不能替代 Dictionary;它的设计目标很明确:避免内存泄漏,同时支持在不修改原类型的前提下扩展对象行为(比如 AOP、诊断、序列化上下文等场景)。
常见错误现象包括:用普通字典存 object → metadata 导致目标对象无法释放;或用 WeakReference 手动管理又容易出现竞态或空引用。
使用场景典型如:
- 给第三方类的实例附加调试 ID 或调用栈快照
- 在序列化器中为每个正在序列化的对象缓存临时状态
- 实现类似 WPF 的依赖属性附加逻辑(但更轻量)
如何正确添加和获取附加数据
关键在于理解它的泛型参数:ConditionalWeakTable 中的 TKey 必须是引用类型,且内部按对象标识(reference equality)匹配,不是值相等。
添加数据只需调用 Add 或更安全的 GetValue(自动初始化):
private static readonly ConditionalWeakTable
注意:
-
GetValue 的工厂委托只会在键首次访问时执行,后续返回缓存值
- 工厂函数内不要捕获外部变量并持有长生命周期引用,否则可能意外延长对象存活
-
TValue 本身不被弱引用保护——如果它是引用类型且被其他地方强引用,它自己不会被 GC;但只要 TKey 被回收,整个键值对就从表中移除
为什么不能用 Dictionary