Наследование / инкапсуляция параллельной коллекции C#

Я создаю пользовательскую коллекцию, которая инкапсулирует ConcurrentDictionary. Я нашел много информации о инкапсуляции / наследовании от общей коллекции, но ничего специфичного для параллельных коллекций. Вот фрагмент кода моего базового случая, а затем несколько общих вопросов.

class ItemCollection
{
    private ConcurrentDictionary<string, Item> Collection;        

    public ItemCollection() { Collection = new ConcurrentDictionary<string, Item>(); }

    public bool TryAdd(string webId, string name) { return Collection.TryAdd(webId, new Item(name)); }
    public bool TryAdd(string webId, Item item) { return Collection.TryAdd(webId, item); }
    public bool TryUpdate(KeyValuePair<string, Item> entry, Data data) 
    {
        Item newItem = entry.Value;
        newItem.AddData(data);            
        return Collection.TryUpdate(entry.Key, newItem, entry.Value);
    }
}
  • Является ли приемлемым инкапсуляция параллельных коллекций таким образом, или это переходит в область создания собственной поточно-ориентированной коллекции из общей коллекции?
  • Является ли пользовательская коллекция поточно-ориентированной?
  • Является ли наследование параллельной коллекции когда-либо приемлемым? Вот так class ItemCollection : ConcurrentDictionary<string, Item> и если да, то каковы некоторые рекомендации, аналогичные этому для наследования от не параллельных коллекций.
  • Как реализовать методы пересылки для таких методов, как Select? Я попробовал серию вариантов, таких как следующие, но не могу заставить его работать:

public IEnumerable<TResult> Select<ItemCollection, TResult>(this ItemCollection source, Func<KeyValuePair<string, Item>, TResult> selector) { return Collection.Select(selector); }

Если я наследую ConcurrentDictionary, это приводит к реализации, каквведите описание изображения здесь

1 ответ

Решение

Вопрос граничит с "слишком широким". Тем не менее, некоторые основные ответы могут быть предоставлены. Для получения более подробной информации вам придется сузить свой вопрос (ы) дальше, занимаясь более мелкими, более конкретными вопросами за раз, и предпочтительно представляя эти вопросы по отдельности.

В это время:

Является ли приемлемым инкапсуляция параллельных коллекций таким образом, или это переходит в область создания собственной поточно-ориентированной коллекции из общей коллекции?

"Приемлемо" - это широкое понятие, но… да, в этом подходе нет ничего принципиально неправильного.

Является ли пользовательская коллекция поточно-ориентированной?

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

Обратите внимание, что TryUpdate() Метод также изменяет переданный объект, что не выполняется потокобезопасным способом. Но это больше о безопасности потоков этого объекта, а не вашей коллекции.

Является ли наследование параллельной коллекции когда-либо приемлемым? Как и в случае с классом ItemCollection: ConcurrentDictionary и, если да, каковы некоторые рекомендации, аналогичные приведенным для наследования от не параллельных коллекций.

Всегда "приемлемо" наследовать незапечатанный класс. Полезно ли это делать - это другое дело. Наследование наиболее полезно, когда унаследованный класс имеет полезные защищенные и / или виртуальные члены, которые производный класс может использовать для фактического расширения или иного изменения поведения унаследованного класса.

В противном случае методы расширения часто являются лучшим подходом.

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

Как реализовать методы пересылки для таких методов, как Select? Я попробовал серию вариантов, таких как следующие, но не могу заставить его работать:

"Методы типа Select()" реализованы как методы расширения и полагаются на сам объект, реализующий IEnumerable<T> (для некоторых таких методов, IEnumerable это достаточно хорошо). Если вы хотите, чтобы ваша пользовательская коллекция могла использовать эти методы, вам нужно будет реализовать соответствующий интерфейс для методов расширения, которые вы хотите использовать с вашим классом.

Естественно, в вашей реализации интерфейса вы можете делегировать фактическую операцию инкапсулированной коллекции.

Другие вопросы по тегам