33

我最近ConditionalWeakTable<TKey,TValue>在搜索IDictionary使用弱引用的类时遇到了这个类,正如这里这里的答案中所建议的那样。

一篇权威的 MSDN 文章介绍了该类并指出:

您可以在 System.Runtime.CompilerServices 命名空间中找到类 ...。它在 CompilerServices 中,因为它不是通用字典类型:我们打算让它只供编译器编写者使用。

后来又一次:

...条件弱表并非旨在成为通用集合...但是,如果您正在编写自己的 .NET 语言并且需要公开将属性附加到对象的能力,您绝对应该查看 Conditional弱表。

与此一致,该类的 MSDN 条目描述为:

使编译器能够将对象字段动态附加到托管对象。

所以很明显,它最初是为了一个非常特定的目的而创建的——帮助 DLR,而System.Runtime.CompilerServices命名空间体现了这一点。但它似乎发现了比这更广泛的用途——即使在 CLR 中也是如此。例如,如果我在ILSpy中搜索ConditionalWeakTable的引用,我可以看到它在 MEF 类和内部 WPF类等中使用。CatalogExportProviderDataGridHelper

我的问题是在编译器编写和语言工具之外使用ConditionalWeakTable是否可以,以及这样做是否存在任何风险,即在未来的 .NET 版本中会产生额外的开销或实现显着变化。(或者应该避免使用类似这样的自定义实现)。

还有进一步的阅读hereherehere关于ConditionalWeakTable如何利用一个隐藏的CLR实现的ephemerons(通过System.Runtime.Compiler.Services. DependentHandle)来处理键和值之间的循环问题,以及这如何不能以自定义方式轻松完成。

4

1 回答 1

23

我看不出使用有什么问题ConditionalWeakTable。如果你需要蜉蝣,你几乎别无选择。

我认为未来的 .NET 版本不会成为问题 - 即使只有编译器会使用此类,Microsoft 仍然无法在不破坏与现有二进制文件的兼容性的情况下更改它。

至于开销 - 与普通字典相比肯定会有开销。拥有许多DependentHandles 可能会很昂贵,类似于有多少WeakReferences 比普通引用更昂贵(GC 必须做额外的工作来扫描它们以查看它们是否需要被清空)。但这不是问题,除非您有很多(数百万)条目。

于 2012-04-22T12:30:35.813 回答