views:

1878

answers:

5

Hello

I am trying to limit the size of my generic list so that after it contains a certain amount of values it wont add any more.

I am trying to do this using the Capacity property of the List object but this does not seem to work.

        Dim slotDates As New List(Of Date)
        slotDates.Capacity = 7

How would people advice limiting the size of a list?

I am trying to avoid doing a statement to check the size after an object is added

Regards

+13  A: 

There is no built-in way to limit the size of a List(Of T). The Capacity property is merely modifying the size of the underyling buffer, not restricting it.

If you want to limit the size of the List, you'll need to create a wrapper which checks for invalid size's. For example

Public Class RestrictedList(Of T)
  Private _list as New List(Of T)
  Private _limit as Integer
  Public Property Limit As Integer 
    Get 
      return _limit
    End Get
    Set 
      _limit = Value
    End Set
  End Property

  Public Sub Add(T value) 
    if _list.Count = _limit Then
      Throw New InvalidOperationException("List at limit")
    End If
    _list.Add(value)
  End Sub
End Class
JaredPar
A: 

You should implement your own list/collection if you need to restrict the maximum quantity of item in it.

Fabian Vilers
A: 

List has no such facility.

The capacity stuff is just a performance optimisation.

You are going to have to roll your own class, derive off list and override the Add implementation.

Sam Saffron
+4  A: 

You'll want to derive a new LimitedList and shadow the adding methods. Something like this will get you started.

public class LimitedList<T> : List<T>
{
    private int limit;

    public LimitedList(int limit)
    {
        this.limit = limit;
    }

    public new void Add(T item)
    {
        if (Count < limit)
            base.Add(item);
    }
}

Just realised you're in VB, I'll translate shortly

Edit See Jared's for a VB version. I'll leave this here in case someone wants a C# version to get started with.

For what it's worth mine takes a slightly different approach as it extends the List class rather than encapsulating it. Which approach you want to use depends on your situation.

Garry Shutler
Your solution will cause problems though because it's still possible for people to bypass the new Add method and use the old one.
JaredPar
Yes, my brief example isn't complete. Just like your brief example doesn't allow you to access the underlying list. I was just showing a different approach.
Garry Shutler
+7  A: 

The problem with some of the solutions given is that there are several different ways to add things to a List<T>: Add, AddRange, Insert, etc.

Consider instead a solution that inherits from Collection<T>:

Public Class LimitedCollection(Of T)
    Inherits System.Collections.ObjectModel.Collection(Of T)

    Private _Capacity As Integer
    Public Property Capacity() As Integer
        Get
            Return _Capacity
        End Get
        Set(ByVal value As Integer)
            _Capacity = value
        End Set
    End Property

    Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As T)
        If Me.Count = Capacity Then
            Dim message As String = String.Format("List cannot hold more than {0} items", Capacity)
            Throw New InvalidOperationException(message)
        End If
        MyBase.InsertItem(index, item)
    End Sub

End Class

This way the capacity is respected whether you Add or Insert.

Kyralessa