Как создать универсальный метод в классе? - PullRequest
3 голосов
/ 28 апреля 2010

Я действительно стараюсь следовать принципу СУХОЙ. У меня есть саб, который выглядит так?

Private Sub DoSupplyModel

        OutputLine("ITEM SUMMARIES")
        Dim ItemSumms As New SupplyModel.ItemSummaries(_currentSupplyModel, _excelRows)
        ItemSumms.FillRows()
        OutputLine("")

        OutputLine("NUMBERED INVENTORIES")
        Dim numInvs As New SupplyModel.NumberedInventories(_currentSupplyModel, _excelRows)
        numInvs.FillRows()
        OutputLine("")   

End Sub

Я бы хотел объединить их в один метод с использованием обобщений. Для записи ItemSummaries и NumberedInventories являются производными от одного базового класса DataBuilderBase.

Я не могу понять синтаксис, который позволит мне выполнять ItemSumms.FillRows и numInvs.FillRows в методе.

FillRows объявлен как Public Overridable Sub FillRows в базовом классе.

Заранее спасибо.

EDIT
Вот мой конечный результат

Private Sub DoSupplyModels()

    DoSupplyModelType("ITEM SUMMARIES",New DataBlocks(_currentSupplyModel,_excelRows)
    DoSupplyModelType("DATA BLOCKS",New DataBlocks(_currentSupplyModel,_excelRows)

End Sub

Private Sub DoSupplyModelType(ByVal outputDescription As String, ByVal type As DataBuilderBase)
    OutputLine(outputDescription)
    type.FillRows()
    OutputLine("")
End Sub

Но чтобы ответить на мой собственный вопрос ... Я мог бы сделать это ...

Private Sub DoSupplyModels()

    DoSupplyModelType(Of Projections)("ITEM SUMMARIES")
    DoSupplyModelType(Of DataBlocks)("DATA BLOCKS")

End Sub

Private Sub DoSupplyModelType(Of T as DataBuilderBase)(ByVal outputDescription As String, ByVal type As T)
    OutputLine(outputDescription)
    Dim type as New DataBuilderBase (_currentSupplyModel,_excelRows)
    type.FillRows()
    OutputLine("")
End Sub

Это правильно?

Сет

Ответы [ 4 ]

3 голосов
/ 28 апреля 2010

Как уже отмечали другие, вам не нужны генерики, чтобы делать то, что вы хотите, но я отвечу на технический вопрос для полноты:

Private Sub MyMethod(Of T As DataBuilderBase)(ByVal instance As T)
    instance.FillRows()
End Sub

А затем вызвать метод, выполнив это:

MyMethod(Of ItemSummaries)(new SupplyModel.ItemSummaries(...))
1 голос
/ 28 апреля 2010

В основном вам нужно указать, что T будет подклассом базового типа, который реализует метод FillRows. В C # это будет выглядеть так

private void myFunction<T>( T someList ) where T : DataBuilderBase {
    someList.FillRows();
}

Найден пример VB.NET на MSDN .

РЕДАКТИРОВАТЬ и Кевин прав, это, вероятно, будет лучше с полиморфизмом.

1 голос
/ 28 апреля 2010

вы можете рефакторинг, чтобы воспользоваться тем фактом, что разделяете общую базу и используете полиморфизм: (В.Б. немного ржавый, вы должны понять)

у вас может быть метод:

Private Sub FillAndOutput(textToOutput as String, filler as DataBuilderBase)
    OutputLine(string)        
    filler.FillRows()
    OutputLine("")
end sub

который вы могли бы назвать:

Private Sub DoSupplyModel
    FillAndOutput("ITEM SUMMARIES",New SupplyModel.ItemSummaries(_currentSupplyModel, _excelRows))
    FillAndOutput("NUMBERED INVENTORIES",New SupplyModel.NumberedInventories(_currentSupplyModel, _excelRows))        

End Sub
0 голосов
/ 28 апреля 2010

В этом случае я не думаю, что рефакторинг универсальной функции оправдан, даже за счет повторения. У вас будет два варианта:

  1. Измените код, чтобы он позволял использовать конструкторы без параметров, и создайте функцию с более высоким уровнем наследования, которая позволит вам указать аргументы, передаваемые в данный момент конструктору.
  2. Используйте явное отражение для создания экземпляра универсального типа и передачи этих аргументов в конструктор.

Любой из этих вариантов включает в себя нетривиальный объем работы с очень небольшим выигрышем (вы переводите три строки кода в одну).

Однако, чтобы ответить на ваш вопрос, VB.NET использует ключевое слово of для указания аргументов универсального типа

Public Sub Foo(Of T)(argument as T)
   ...
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...