Вопрос, наследующий класс List (of T)

Я хочу реализовать класс очереди приоритетов. Когда элемент добавляется с более высоким приоритетом, он помещается в очередь перед очередью, а затем добавляет в конец очереди.

Простые несколько строк кода

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

Теперь вызывающая функция пытается найти элементы в очереди таким образом ....

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

.....

программа выводит 0! Если добавить свойство Count(), все будет хорошо. Я бы подумал, что унаследованный класс должен вызвать функцию подсчета базового класса. Обратите внимание, что граф отображается в intellisense, даже если у меня нет реализации в производном классе.

Ответ 1

Ваша проблема в том, что вы оба наследуете от List(of T), и у вас есть свойство экземпляра этого типа, в котором вы храните свои данные. Когда в указанном выше коде вызывается Count, он использует свойство Count из родительского List(of T), который не находится там, где вы храните свои данные.

Лучшей идеей было бы унаследовать от object и иметь PriorityQueue(of T) реализовать ICollection и IEnumerable(of T) явно. Вам не нужно вообще менять внутреннюю реализацию, вам просто нужно добавить код для поддержки этих интерфейсов.

Ответ 2

Вы добавляете свои элементы в закрытый список экземпляров (_list.Insert/_list.Add), а не в базовый список (Me.Insert/Me.Add)

На самом деле, я думаю, что используя частный список, как вы делаете, и добавление свойства Count является лучшим дизайном, чем наследование из списка.

Как указывает Адам Робинсон, вы можете рассмотреть возможность внедрения некоторых или всех IEnumerable <T> , ICollection <T> , ICollection, IEnumerable, если вы хотите, чтобы пользователи вашего класса могли, например, перебирать элементы в очередь.

Это не является абсолютно необходимым, если ваши вызывающие лица используют его только как очередь (вызов Enqueue или Dequeue).

Стандартный класс очереди Queue <T> реализует IEnumerable <T> , ICollection и IEnumerable, реализующие, по крайней мере, это было бы хорошо для согласованности.