views:

258

answers:

4

I have several different lists I want to call. They all have the same format for the class: id, value, description, order. Instead of creating a bunch a classes to return the all of the many lists, I wanted to use generics and just TELL it what kind of list to return. However, I can not figure out how to populate the classes.

Here are 2 examples of function in my calling code. This should indicate the type of list and the stored proc used to get the data:

Public Function getTheEyeColors()
    Dim glEyeColors As New GenericList
    Return glEyeColors.GetALList(Of EyeColor)("GetAllEyeColors")
End Function

Public Function getTheHairColors()
    Dim glHairColors As New GenericList
    glHairColors.GetALList(Of HairColor)("GetAllHairColors")
End Function

And here is the code I am trying to use to build the generic list...

Public Function GetALList(Of t)(ByVal storedproc As String) As List(Of t)

    Dim lstGenericList As New List(Of t)
    Dim oGenericListItem As t
    Dim oProviderFactory As New ProviderFactory
    Dim oConnection As DbConnection
    Dim oReader As System.Data.IDataReader
    Dim oFactory As DbProviderFactory
    Dim oFileMgt As New FileMgt
    Dim oCmd As DbCommand

    oFactory = oProviderFactory.GetFactory
    oConnection = oProviderFactory.GetProviderConnection(oFactory)
    oCmd = oConnection.CreateCommand
    oCmd.CommandType = CommandType.StoredProcedure

    oCmd.CommandText = storedproc

    Using (oConnection)

        oConnection.Open()
        oReader = oCmd.ExecuteReader()

        While oReader.Read
            HERE IS WHERE I AM NOT SURE HOW TO POPULATE THE EYECOLOR OR HAIRCOLOR CLASS
            lstGenericList.Add(oGenericListItem)
        End While

        oConnection.Close()

    End Using

    Return lstGenericList

End Function
+8  A: 

You could add two generic constraints; I don't know how to express them in VB, but here's the C# version:

  • T : new() - there has to be a parameterless constructor
  • T : ICommonInterface - T has to implement an interface

You then put the common properties (ID, Value, Description, Order) into the interface, and you'll be able to create a new T(), set the properties and add it to the list.

EDIT:

The VB Syntax to specify that it must both be creatable and implement an interface is:

  • (Of T As {ICommonInterface, New})
Jon Skeet
+1 for beating me to it. The VB syntax in question is `(Of T As ICommonInterface)`, FYI
Welbog
And the parameterless constructor one? Feel free to just edit the answer to include the VB syntax instead :)
Jon Skeet
THANK YOU!!!!!!!
A: 

Would it not be an easier option to create an interface something like IColor that both HairColor and EyeColor implement. Then you can return a list of IColor and based on the Stored Procedure you have called you should be able to determine what objects they relate to i.e. Hair Color / Eye Color.

James
And even better, imagine the confusion on your co-worker's faces when you said "I created HairColor so that it implements IColor, and EyeColor also implements IColor." :)
GalacticCowboy
Duh the reason you would use interfaces in this particular example is because you have 2 classes with common properties that you need to process....what looks common about both classes....they are both colors! The example I gave was exactly that....an example, to demonstrate what he/she could do, the naming of the interface is entirely down to preference.
James
A: 

The way Jon recommends to do it is probably a better way to go, but another way I've seen this done is the FillObject method in the DotNetNuke architecture. Basically it's a conventions based method that uses reflection to match the properties on an object to the values of a dataset.

I personally don't like this method, but it does mean you don't have to create a new implementation of the code to hydrate the object for each stored procedure.

The code is available in the full source download in the DNN project.

lomaxx
A: 
While oReader.Read
  HERE IS WHERE I AM NOT SURE HOW TO POPULATE THE EYECOLOR OR HAIRCOLOR CLASS

Check out LinqToSql (System.Data.Linq) . You might be re-inventing it.

David B