Почему ConcurrentBag не реализует ICollection ?

  • Последовательный стиль форматирования
  • Хорошее использование пробела
  • Используя короткие, но понятные имена
  • Не слишком много комментариев (как Вы упоминаете), но когда я делаю, комментируют whys кода, и если применимо, , почему nots (то, почему некоторый другой implemention не использовался, особенно если это походит на него, должно быть очевидно сделать так).
  • не оптимизируют код, пока профилировщик не говорит мне его медленное или неэффективное
28
задан Doron Yaacoby 10 April 2011 в 12:42
поделиться

2 ответа

A List<T> не является параллельным, и поэтому он может реализовывать ICollection<T>, который дает вам пару методов Contains и Add. Если Contains вернет false, вы можете безопасно позвонить Add, зная, что это удастся.

A ConcurrentBag<T> является одновременным, и поэтому он не может реализовать ICollection<T>, потому что возвращаемый ответ Contains может оказаться недействительным к тому времени, когда вы вызовете Add. Вместо этого он реализует IProducerConsumerCollection<T>, который предоставляет единственный метод TryAdd, который выполняет работу как Contains, так и Add.

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

Вот простой пример:

public class Processor
{
    /// <summary>
    /// Process a traditional collection.
    /// </summary>
    /// <param name="collection">The collection.</param>
    public void Process(ICollection<string> collection)
    {
        Process(item =>
            {
                if (collection.Contains(item))
                    return false;
                collection.Add(item);
                return true;
            });
    }

    /// <summary>
    /// Process a concurrent collection.
    /// </summary>
    /// <param name="collection">The collection.</param>
    public void Process(IProducerConsumerCollection<string> collection)
    {
        Process(item => collection.TryAdd(item));
    }

    /// <summary>
    /// Common processing.
    /// </summary>
    /// <param name="addFunc">A func to add the item to a collection</param>
    private void Process(Func<string, bool> addFunc)
    {
        var item = "new item";
        if (!addFunc(item))
            throw new InvalidOperationException("duplicate item");
    }
}
34
ответ дан 28 November 2019 в 03:13
поделиться

Есть SynchronizedCollection<T> , реализует как IList<T> и ICollection<T>, а также IEnumerable<T>.

6
ответ дан 28 November 2019 в 03:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: