Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple existing implementation of ICollection<T>

Tags:

c#

.net

generics

Is there a simple implementation of ICollection<T> in .NET framework? I.e. a collection class with ability to add and remove items, but without indexing. Collection<T> definitely does not fit, as it implements IList as well and so elements can be accessed by index.

Exposing Collection<T> or List<T> as ICollection<T> will not work in my case too, because I need to inherit my own class from it, and a class inherited from any other class that implements IList<T> will have indexing as well.

I know it is not a big deal to implement one myself, but just thought it should already exist, searched for but did not found anything similar.

like image 397
Aleksey Shubin Avatar asked Jan 31 '15 03:01

Aleksey Shubin


1 Answers

Here's a list of classes that implement ICollection<T> in the System.Collections namespace:

System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>
System.Collections.Generic.Dictionary<TKey, TValue>
System.Collections.Generic.HashSet<T>
System.Collections.Generic.LinkedList<T>
System.Collections.Generic.List<T>
System.Collections.Generic.SortedDictionary<TKey, TValue>
System.Collections.Generic.SortedList<TKey, TValue>
System.Collections.Generic.SortedSet<T>
System.Collections.ObjectModel.Collection<T>
System.Collections.ObjectModel.ReadOnlyCollection<T>
System.Collections.ObjectModel.ReadOnlyDictionary<TKey, TValue>
System.Collections.ObjectModel.WeakReadOnlyCollection<T>

But all of those implementations add extra functionality, and since you want to inherit from an implementation, but only expose ICollection<T> methods, using any of them is not really an option.

The only choice you have is to implement your own. It's easy enough to do. You just need to wrap a suitable implementation of ICollection<T>. Here's one that uses a List<T> by default, but also allows derived classes to use a specific type of ICollection<T>:

class SimpleCollection<T> : ICollection<T>
{

    ICollection<T> _items;


    public SimpleCollection() {
        // Default to using a List<T>.
        _items = new List<T>();
    }

    protected SimpleCollection(ICollection<T> collection) {
        // Let derived classes specify the exact type of ICollection<T> to wrap.
        _items = collection;
    }

    public void Add(T item) { 
        _items.Add(item); 
    }

    public void Clear() { 
        _items.Clear(); 
    }

    public bool Contains(T item) { 
        return _items.Contains(item); 
    }

    public void CopyTo(T[] array, int arrayIndex) { 
        _items.CopyTo(array, arrayIndex); 
    }

    public int Count
    {
        get { return _items.Count; }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public bool Remove(T item)
    {
        return _items.Remove(item);
    }

    public IEnumerator<T> GetEnumerator()
    {
        return _items.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return _items.GetEnumerator();
    }
}

This is going beyond what you're after, but if, for example, you wanted unique items to be stored, you could derive from this and provide a HashSet<T> as the collection type to wrap:

class UniqueCollection<T> : SimpleCollection<T>
{
    public UniqueCollection() : base(new HashSet<T>()) {}
}
like image 143
reduckted Avatar answered Oct 02 '22 16:10

reduckted