Почему мне нужно преобразовать ConcurrentDictionary в IDictionary, чтобы использовать Add()?

Если у меня есть ConcurrentDictionary и я хочу использовать функцию Add(), мне нужно привести к IDictionary:

var cd = new ConcurrentDictionary<int, int>();
cd.Add(1, 1);  // Compile error: does not contain a definition for 'Add'
IDictionary<int, int> id = cd;
id.Add(1, 1);  // Works

Вопрос ConcurrentDictionary и IDictionary говорит мне, что это потому, что ConcurrentDictionary реализует IDictionary явно, используя частные методы.

Мой вопрос: Почему ConcurrentDictionary реализовано именно так? В чем преимущество сокрытия использования реализованного интерфейса?


person Jonathan    schedule 18.02.2014    source источник


Ответы (2)


Мой вопрос: почему ConcurrentDictionary реализован именно так?

Я считаю, что это должно побудить вас задуматься о последствиях параллелизма - что несколько потоков могут одновременно записывать одни и те же ключи. Таким образом, добавление существующего ключа с меньшей вероятностью будет ошибкой программирования, и его следует тщательно обдумать.

  • Если вы хотите безоговорочно перезаписать, используйте индексатор
  • Если вы хотите добавить или обновить, где обновление может использовать существующее значение, используйте AddOrUpdate
  • Если вы хотите добавить, если это возможно, но не перезаписывать какое-либо существующее значение, используйте TryAdd

Если вам часто требуется существующее поведение Add, вы всегда можете написать свой собственный метод расширения.

person Jon Skeet    schedule 18.02.2014
comment
Вероятно, это также связано с тем, что IDictionary.Add просто реализуется как if (!TryAdd(...)) throw ...;, что настолько тривиально, что даже в тех случаях, когда это имеет смысл для параллельного словаря, у вызывающей стороны все еще есть возможность сделать то же самое, не прибегая к доступу к словарю. через IDictionary. - person ; 18.02.2014

Я думаю, что вы можете попробовать использовать метод TryAdd() или AddOrUpdate() из ConcurrentDictionay, как вы можете видеть здесь.

http://msdn.microsoft.com/es-es/library/dd287191(v=vs.110).aspx

person Oscar Bralo    schedule 18.02.2014