neverendingqs
neverendingqs

Reputation: 4276

Is there a built-in data structure in C# that only allows items to be added, but not removed?

I would like to pass an array-like or set-like structure where other classes append to it, but are never allowed to remove from it.

Is there a built-in data structure in C# that manages this?

Upvotes: 3

Views: 379

Answers (4)

Ivan Stoev
Ivan Stoev

Reputation: 205579

Is there a built-in data structure in C# that only allows items to be added, but not removed?

No, there isn't.

But there is one that easily allows you to create your own - Collection<T> class which can be found inside the System.Collections.ObjectModel namespace.

public class Collection<T> : IList<T>, ICollection<T>, IEnumerable<T>, 
    IEnumerable, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>

All you need is to create a derived class, override a few methods and throw NotSupportedException like this

public class AddOnlyCollection<T> : System.Collections.ObjectModel.Collection<T>
{
    protected override void ClearItems() { throw new NotSupportedException(); }
    protected override void RemoveItem(int index) { throw new NotSupportedException(); }
    protected override void SetItem(int index, T item) { throw new NotSupportedException(); }
}

UPDATE: As correctly mentioned in the comments by Tseng, the above is not considered a good practice, so a better approach would be to define your own interface and use the above just for easy implementing it, like this

public interface IAddOnlyCollection<T> : IReadOnlyCollection<T> // could be IReadOnlyList<T> if you wish
{
    void Add(T item);
}

public class AddOnlyCollection<T> :
    System.Collections.ObjectModel.Collection<T>, IAddOnlyCollection<T>
{
    // Same as above
}

UPDATE 2: It turns out that the class ReadOnlyCollection<T> from the same namespace is even a better choice. All you need is to inherit it and define Add method. No interface is needed in that case.

So the full final solution looks like this

public class AddOnlyCollection<T> : ReadOnlyCollection<T>, ICollection<T>
{
    public void Add(T item) { Items.Add(item); }
}

Upvotes: 1

AnjumSKhan
AnjumSKhan

Reputation: 9827

You have to build your own class, and you can make use of following :

  1. Array.AsReadOnly() method.
  2. ReadOnlyCollection.

Upvotes: 0

GendoIkari
GendoIkari

Reputation: 11914

You can create your own class that implements IList. See this answer for details:

How do I override List<T>'s Add method in C#?.

You can't just inherit from List and override Remove because Remove is not virtual. But your own class could have a private List variable that you use to track your items. You have to implement Remove if you do this, but your Remove method could just throw a NotSupportedException.

Upvotes: 0

Ivan G.
Ivan G.

Reputation: 5215

No, you have to build your own interface based on one of the existing implementations.

Upvotes: 1

Related Questions