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 resultPrivate 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开发者_JAVA百科")
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:
- Refactor your code so that it allows for parameterless constructors and create a function at a higher level of inheritance that allows you to specify the arguments currently being passed to the constructor.
- Use explicit reflection to instantiate the generic type and pass those arguments to the constructor.
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
精彩评论