Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
282 views
in Technique[技术] by (71.8m points)

.net - Maximum capacity collection in c#

In the .Net BCL is there a collection data structure similar to list that has a maximum capacity, say configured to 100 items, which when item 101 is added the original first item is popped/removed from the collection thus ensuring the item count never exceeds 100.

I’m using .net 3.5

Thanks in advance

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There is no such collection available but one is fairly easy to write. The best way to do this is to create a new collection type that encapsulates an existing collection type.

For example

public class FixedSizeList<T> : IList<T> {
  private List<T> _list = new List<T>();
  private int _capacity = 100;

  public void Add(T value) {
    _list.Add(value);
    while ( _list.Count > _capacity ) {
      _list.RemoveAt(0);
    }
  }

  // Rest omitted for brevity
}

A couple of answers suggested inheritance as a mechanism. This is certainly not a good route especially if you are deriving from one of the generic collections. These collections are not designed to be inherited from and it is very easy to accidentally circumvent any checks you make an capacity as the result of an Add or Remove method.

The primary reason is that these methods are not virtual so they cannot be overridden. You would be forced to either declare an Add method with a different name (thus confusing your users) or re-declare Add with the new syntax. The latter is a very unsafe because as soon as an instance of your class is passed to a reference of the base type, all of your methods will not be called and the list can grow past capacity.

EDIT

As the comment section discussion has indicated, implementing List<T> is not the best approach here. The reason why is that it violates the substitution principle in several cases. The easiest way to display the problem is imagine if my implementation was passed to the following method. This code should pass for any IList<T> implementation but would fail in this case if the list was at capacity.

public void Example<T>(IList<T> list, T value) {
  var count = list.Count;
  list.Add(value);
  var addedValue = list[count];
}

The only collection interface that can be validly implemented for the specified collection is IEnumerable<T>. I've left my implementation up there as an example. But see ShuggyCoUk's answer for an IEnumerable<T> implementation:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...