views:

359

answers:

1

I have a function which I need to call for three different types, with the underlying logic remaining the same for all the different types, so I figured it would be best to write this function using generics.

Here is the basic outline of the classes and functions involved:

'PO Base class'
Public MustInherit Class ProductionOrder
     Public MustInherit Class Collection(Of T)
          Inherits System.Collections.Generic.Dictionary(Of Long, T)
     End Class
     '....'
End Class

Public Class ProfileProductionOrder
     Inherits ProductionOrder
     Public Class Collection
          Inherits ProductionOrder.Collection(Of ProfileProductionOrder)
     End Class
     '....'
End Class

Public Class UnitProductionOrder
     Inherits ProductionOrder
     Public Class Collection
          Inherits ProductionOrder.Collection(Of UnitProductionOrder)
     End Class
     '....'
End Class

Public Class CrateProductionOrder
     Inherits ProductionOrder
     Public Class Collection
          Inherits ProductionOrder.Collection(Of CrateProductionOrder)
     End Class
     '....'
End Class

'Generic function, intended to work on profile, unit, and crate production orders.'
'This method resides in the base class of the GUI.'
Protected Sub FillPOCells(Of T As ProductionOrder.Collection(Of ProductionOrder)) _
    (ByVal dgv As DataGridView, ByVal ProductionOrders As T)
     '...do some stuff'
End Sub

'This function resides in the Profile child GUI class.'
Protected Sub LoadDataGridViewPOs()
     Dim dgv As DataGridView
     Dim ProductionOrders As ProfileProductionOrder.Collection
     '....'
     'Fill PO Cells'
     FillPOCells(Of ProfileProductionOrder.Collection)(dgv, ProductionOrders)
     '....'
End Sub

The ProductionOrder base and child classes compile, as does the FillPOCells function. But when I call FillPOCells inside LoadDataGridViewPOs the compiler complains that "Type argument 'ProfileProductionOrder.Collection' does not inherit from or implement the constraint type 'ProductionOrder.Collection(Of ProductionOrder)'.

Also, here is some explanation about why things are set up this way. My predecessor set up the convention of putting the collection of an object as a subclass within it, so it's easy to refer to it as Obj.Collection. Next, the reason we need three different types of production orders is because they are treated differently and stored in different tables and such on the back end. Lastly, I realize I could implement this fairly easily without getting this particular generic function to work, but I'm looking at this as a learning experience to improve my understanding of generics and OO design.

So the question is, why am I getting that compiler error and how should I change my class and generics design to accomplish what I have in mind?

If you need any further explanation about what I'm trying to do or how I have things set up let me know. The main idea is to have a function that can take a collection who's elements belong to one of the ProductionOrder child classes, and run operations on these elements that only use the functionality held in their ProductionOrder base class (hence why either of the child types is okay to operate on in the function).

+1  A: 
'PO Base class'
Public MustInherit Class ProductionOrder(Of T)
     Public MustInherit Class Collection
          Inherits System.Collections.Generic.Dictionary(Of Long, T)
     End Class
     '....'
End Class

Public Class ProfileProductionOrder
     Inherits ProductionOrder(Of ProfileProductionOrder)
     '....'
End Class

Public Class UnitProductionOrder
     Inherits ProductionOrder(Of UnitProductionOrder)
     '....'
End Class

Public Class CrateProductionOrder
     Inherits ProductionOrder(Of CrateProductionOrder)
     '....'
End Class

That is a lot simpler according to me. But I higly doubt you need the CollectionClass.

chrissie1
Hmm this seems to make sense, I'll try it out and let you know, thanks!
Daniel
Well I changed the functions as well to reflect this and it seems to be working. Thanks for the help, though I don't quite understand why it works with this change...
Daniel
Oh, one small thing, Collection shouldn't be abstract now because it needs to be instantiated.
Daniel