为什么Concurrent Dictionary没有显式的Add()方法?

8
我在想为什么ConcurrentDictionary没有一个Add方法在Visual Studio IDE中是可见的。我只能看到一些TryX方法,比如TryAdd、TryUpdate等。我可以看到ConcurrentDictionary实现了IDictionary接口,如果将其转换为IDictionary,则可以获得Add方法。通过iLSpy查看类,我可以看到Add方法被完全实现,实际上在底层调用了Concurrent TryAdd方法。我希望在Add方法上看到某种属性来隐藏它,但我没有看到任何东西。这是否被微软内置到IDE中默认隐藏Add方法? 如果有人能解释一下这个问题就好了。
2个回答

9
他们不鼓励使用Add方法,因为如果字典中已经存在相同的键,则该方法会抛出异常。对于大多数字典,开发人员可以编写代码以保证在任何正常情况下都不会抛出异常。然而,要在并发字典中执行此操作(Contains后跟Add),您需要在访问字典的方法中使用独占锁,这将破坏并发字典的整个目的。 TryAdd结合了ContainsAdd检查,而无需锁定字典,并允许您再次编写在正常情况下不会引发异常的代码。

7

1
@AlexG 我想这很可能是因为你不应该使用 Add,如果其他线程可能同时修改同一个字典,那么正确使用它就很困难。 - user743382
这只是显式实现的一个副作用,我从未真正考虑过。您可以从支持相同方法的2个接口实现。否则,.Net将不知道应调用哪个版本,因此必须在具体类中隐藏它。我认为ConcurrentDictionary上没有冲突的接口(正如您所说),这样做只是为了让您使用并发方法并更加思考如何使用它。 - Lenny D
2
实际上我在想微软为什么要从IDictionary派生ConcurrentDictionary!ConcurrentDictionary应该鼓励您使用TryAdd()而不是ContainsKey()/Add()对,因为后者在并发上下文中不安全。这是通过隐藏这些方法来完成的。但是一旦使用IDictionary,并将ConcurrentDictionary传递给它,任何并发安全性都会消失!那么:为什么微软要这样做呢? - mmmmmmmm
2
链接已失效(微软开发者网络的惊喜!)。替代方案:https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/explicit-interface-implementation - Michael Brown
1
@mmmmmmmm:更好的问题是,如果想要使用ConcurrentDictionary(线程安全字典),为什么有人会将其强制转换为IDictionary。 - Tim Schmelter
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接