Thursday, March 31, 2011

How do I code these generic functions and classes inheritances correctly? (VB .NET)

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).

From stackoverflow
  • '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.

    Daniel : 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.

0 comments:

Post a Comment