I am really trying to follow the DRY principle. I have a sub that looks like this?
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
I would like to collapse these into a single method using generics. For the record, ItemSummaries and NumberedInventories are both derived from the same base class DataBuilderBase.
I can't figure out the syntax that will allow me to do ItemSumms.FillRows and numInvs.FillRows in the method.
FillRows is declared as Public Overridable Sub FillRows
in the base class.
Thanks in advance.
EDIT
Here is my end result
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
But to answer my own question...I could have done this...
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
Is that right?
Seth
As others have pointed out, you don't need generics to do what you want, but I will answer the technical question for completeness:
Private Sub MyMethod(Of T As DataBuilderBase)(ByVal instance As T)
instance.FillRows()
End Sub
And then call the method by doing this:
MyMethod(Of ItemSummaries)(new SupplyModel.ItemSummaries(...))
you can refactor to take advantage of the fact that the share a common base and use polymorphism: (VB a bit rusty, you should get the idea)
you could have a method:
Private Sub FillAndOutput(textToOutput as String, filler as DataBuilderBase)
OutputLine(string)
filler.FillRows()
OutputLine("")
end sub
which you could call:
Private Sub DoSupplyModel
FillAndOutput("ITEM SUMMARIES",New SupplyModel.ItemSummaries(_currentSupplyModel, _excelRows))
FillAndOutput("NUMBERED INVENTORIES",New SupplyModel.NumberedInventories(_currentSupplyModel, _excelRows))
End Sub
Basically you need to specify that T will be a subclass of the base type that implements FillRows
method. In C# this would look like so
private void myFunction<T>( T someList ) where T : DataBuilderBase {
someList.FillRows();
}
Found a VB.NET example on MSDN .
EDIT and Kevin is right, this would probably be handled better with polymorphism.
In this case I don't think that refactoring to a generic function is justifiable, even at the expense of repeating yourself. You would have two options:
Either of those options involves a non-trivial amount of work with very little gain (you're translating three lines of code into one).
However, to answer your question, VB.NET uses the of
keyword to specify generic type arguments
Public Sub Foo(Of T)(argument as T)
...
End Sub
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.