C# 从ConcurrentDictionary转换为IDictionary
从ConcurrentDictionary到IDictionary的转换是否会切断线程安全的实现,因为IDictionary没有GetOrAdd和AddOrUpdate方法?C# 从ConcurrentDictionary转换为IDictionary,c#,.net,concurrency,thread-safety,C#,.net,Concurrency,Thread Safety,从ConcurrentDictionary到IDictionary的转换是否会切断线程安全的实现,因为IDictionary没有GetOrAdd和AddOrUpdate方法?IDictionary只是一个接口。如果对其进行强制转换,结果是ConcurrentDictionary的实现,缺少GetOrAdd和AddOrUpdate方法 假设您仍然可以使用属性和and方法(代替GetOrAdd和AddOrUpdate)方法,并且您的强制转换对象仍然是线程安全的(因为底层实现是ConcurrentDi
IDictionary
只是一个接口。如果对其进行强制转换,结果是ConcurrentDictionary的实现,缺少GetOrAdd
和AddOrUpdate
方法
假设您仍然可以使用属性和and方法(代替
GetOrAdd
和AddOrUpdate
)方法,并且您的强制转换对象仍然是线程安全的(因为底层实现是ConcurrentDictionary
)。它只是没有公开ConcurrentDictionary的一些方法
您可能会发现或有助于理解接口。生成的对象仍然是一个并发字典。像Add或Remove这样的调用使用底层实现TryAdd和TryRemove(这是线程安全的)。将对象强制转换为其他类型不会更改对象本身
另外,为了澄清,您可以使用诸如ILSpy之类的工具来查看默认IDictionary方法的实现情况,以及它们是否仍然是线程安全的。这就像通过
IDictionary
形状的键孔查看大的ConcurrentDictionary
对象一样-您只能看到IDictionary
形状,但它仍然是ConcurrentDictionary
简短回答否
您正在通过接口操作对象,因此仍在使用具体的实现。您不会丢失任何功能或其方法。他们只是不可用
另一方面,向下投射时需要显式投射,向上投射时不需要显式投射-这样做总是安全的。确切地说,“切割”是什么意思?它是否将其从
ConcurrentDictionary
中删除?否。是否可从IDictionary
界面获取?不。@JamesMichaelHare:他的意思是,如果您强制转换为IDictionary
,是否会使生成的对象线程不安全?换句话说,它能把它变成普通的字典吗?它仍然是线程安全的吗?是的,只要没有这些操作就可以了。也就是说,如果你需要一个原子的GetOrAdd()
,那你就倒霉了。@JamesMichaelHareGetOrAdd()
不是原子的。委托在内部锁之外执行,以防止死锁。请看@mikez:是的,对不起,原子是个错误的词语选择。我的错。我的意思是,如果实际的Add()不存在,它将被同步,因此只有一个竞争对手实际执行Add(),但是正如您从MSDN中正确指出的那样,多个同时调用方可能会执行委托并最终生成一个被忽略的不需要的项。您还可以查看MSDN文档,了解ConcurrentDictionary对IDictionary
方法的实现:抱歉,但是ConcurrentDictionary添加了两个新方法并隐藏了其他方法,因此它的实现只能为新方法添加线程安全,而不能为隐藏方法添加线程安全。MSDN文档并没有阐明这一点,所以我问了它。但在我阅读了最好的评论并查看了ConcurrentDictionary原型之后,我看到了它没有扩展Dictionary的地方,这让我确信,将它转换为IDictionary将间接使用扩展版Dictionary是不可能的。