views:

440

answers:

2

I want to implement a priority queue class. When an item is added at a higher priority it is pushed to the front of the queue instead adding to the end of queue.

Simple few lines of code

Public Class PriorityQueue(Of T)
    Inherits List(Of T)

    Private _list As New List(Of T)

    Public Sub Enque(ByVal item As T, Optional ByVal pushToFront As Boolean = False)
        If pushToFront = True Then
            _list.Insert(0, item)
        Else
            _list.Add(item)
        End If
    End Sub
    Public Function Deque() As T
        If _list.Count <> 0 Then
            Dim item As T = _list(0)
            _list.RemoveAt(0)
            Return item
        Else
            Throw New InvalidOperationException
        End If
    End Function
   End Class


Now the the calling function tries to find the elements in the queue thus ....

dim _q as new PriorityQueue(Of integer)
_q.Enque(1)
_q.Enque(2)
msgbox(_q.Count())

.....

the program prints out 0! If add a Count() property then everything is fine. I would have thought the inherited class should call the base class's Count function. Note that the Count shows up in intellisense even if I have no implementation in the derived class.

+4  A: 

You are adding your items to a private list instance (_list.Insert / _list.Add) rather than the base List (Me.Insert / Me.Add)

In fact I think using a private list as you are doing, and adding a Count property is a better design than inheriting from List.

As Adam Robinson points out, you could consider implementing some or all of IEnumerable<T>, ICollection<T>, ICollection, IEnumerable if you want users of your class to be able to, for example, iterate over items in the queue.

This isn't strictly necessary if your callers only ever use it as a queue (call Enqueue or Dequeue).

The standard queue class Queue<T> implements IEnumerable<T>, ICollection, and IEnumerable implementing at least these would be good for consistency.

Joe
+4  A: 

Your issue is that you're both inheriting from List(of T) and you have an instance property of that type, which is where you're storing your data. When Count is called in your above code, it's using the Count property from your parent List(of T), which isn't where you're storing your data.

A better idea would be for you to inherit from object and have PriorityQueue(of T) implement ICollection and IEnumerable(of T) explicitly. You shouldn't have to change your internal implementation at all, you'll just have to add code to support those interfaces.

Adam Robinson