Generic Lists

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I have a base class called DataElement. Then I have several classes that
inherit from this class, such as Aor, Aor0, plus a bunch more. Each of these
classes that inherit from DataElement have a Shared Function and an instance
method that returns a List(of Aor) or List(of Aor0), etc., see below for
basic class structures.

Public Class DataElement
End Class

Public Class Aor
Inherits DataElement

Public Function LoadFullList() as List(of Aor)
Return GetFullList()
End Function

Public Shared Function GetFullList() as List(of Aor)
End Function

End Class

Then someplace else in the my application I have a screen that works with
DataElements and needs to call the GetFullList or LoadFullList and I can't
figure out a way to accomplish this. I could put the LoadFullList method
into the DataElement class, but then the return type would have to be List(of
DataElement) and then I wouldn't be able to handle the returned list in the
method that I want because it wouldn't be List(of Aor).

Can someone help me out here.
 
Hi Paul,

Since Aor is derived from DataElement, it certainly would be able to return
a List(of Aor). It could return a list of any type that inherits
DataElement.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
A watched clock never boils.
 
The is not what my problem is. My problem in that I have wanother procedure
that is trying to deal with this list, but it is trying to do it at a
dataelement level

Public Sub DoSomethingWithList(element as DataElement)
dim list as List(of DataElement = element.LoadFullList()
End Sub

Because element.LoadFullList() returns list(of Aor) it cannot be converted
to List(of DataElement).
 
Hi Paul,

Forgive me for not recognizing the Generic syntax in your posts. I haven't
delved into the VB.Net Generic syntax until now. Now that I understand your
dilemma fully, I think I can help you resolve your issue.

If you want to take full advantage of Generics, you need not create a base
class and a number of inherited classes. You can define a single class with
Generic methods that takes type parameters. Example:

Public Class DataElement

Public Function LoadFullList (Of ListType) ( ) as ListType
Return GetFullList (Of ListType) ( )
End Function

Public Shared Function GetFullList() (Of ListType) as ListType
End Function

End Class

The class is not Generic, but both methods are. You can then call either
method, passing the type of return value that you want from it, and it will
return that type.

I'm still not sure I'm understanding your question fully, though. Let me
know if I've missed something.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
A watched clock never boils.
 
I think that this might be what I'm looking for. I'll give it a try later
today. Thanks.
 
OK I tried it and I'm still missing how I can do something. Below is a
simple example of the Class Structure that I have to test this out. Just
paste this onto a form a with a button and a textbox

Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim a As New Aor

DoSomething(a)

TextBox1.Text &= Microsoft.VisualBasic.ControlChars.CrLf
Dim list2 As List(Of Aor) = Aor.GetFullList(Of Aor)()
For Each a2 As Aor In list2
TextBox1.Text &= a2.ID & ", "
Next
End Sub

Public Sub DoSomething(ByVal element As DataElement)
Dim list As List(Of xxxxx) = element.LoadFullList(Of xxxxx)()
'The below works, but I don't know how to make the above work
'Dim list As List(Of Aor) = element.LoadFullList(Of Aor)()

For Each a2 As DataElement In list
TextBox1.Text &= a2.ID & ", "
Next
End Sub
End Class

Public Class DataElement

'bunch of code to provide base functionality for all my other classes
Private _ID As Int32
Public Property ID() As Int32
Get
Return _ID
End Get
Set(ByVal value As Int32)
_ID = value
End Set
End Property

Protected Shared Sub Load(ByVal row As System.Data.DataRow, ByVal
element As DataElement)
Dim r As New Random
element.ID = r.Next
End Sub

Protected Shared Function Load(Of ListType As {DataElement, New})(ByVal
ds As System.Data.DataSet) As List(Of ListType)
Dim list As New List(Of ListType)

'If ds IsNot Nothing AndAlso ds.Tables.Count > 0 Then
' For Each row As System.Data.DataRow In ds.Tables(0).Rows
' Dim element As DataElement = Me.Clone
' DataElement.Load(row, element)
' list.Add(element)
' Next
'End If
For counter As Int32 = 0 To 5
Dim element As New ListType
DataElement.Load(ds.Tables(0).NewRow, element)
list.Add(element)
Next

Return list
End Function

Public Overridable Function LoadFullList(Of ListType As {DataElement,
New})() As List(Of ListType)
Throw New NotImplementedException
End Function
End Class

Public Class Aor
Inherits DataElement

Public Overrides Function LoadFullList(Of ListType As {DataElement,
New})() As List(Of ListType)
Return Aor.GetFullList(Of ListType)()
End Function

Public Shared Function GetFullList(Of ListType As {DataElement, New})()
As List(Of ListType)
Dim list As New List(Of ListType)
Dim ds As New System.Data.DataSet
ds.Tables.Add(New System.Data.DataTable)
list = DataElement.Load(Of ListType)(ds)

Return list
End Function
End Class
 
Hi Paul,

You're making me work too hard! I don't do VB.Net much these days! ;-)

I'm a bit confused. The first thing I noticed is that you haven't declared a
Generic class called "List(Of ListType)." But you're trying to use one.
Would this be the System.Collections.Generic.List class?

Also, I'm not entirely clear what you're trying to do here. This is, I
think, the other thing that has had me stymied in my attempt to help you.
Let me see if I can guess. You want a class that has a static (Shared)
method to return a List of various types. But you want that class to return
a List of whatever type that class happens to be. Am I right?

If so, I see you're delving into Inheritance again, and that isn't
necessary. Perhaps my type name confused you. Sounds like we've both been a
bit confused! The tricky part, if I read your requirements right, is the
static (Shared) function. A Shared class cannot be Generic, but a shared
method can take a Generic parameter. So, you would need to declare both the
class and the method to take type parameters, but they could not be the
same, as the method is static (Shared). In other words, the method does not
know what type an instance of the class is. So, you class definition would
look more like the following:

Public Class DataElement(Of T)

Public Function LoadFullList() _
As List(Of T)
Return GetFullList(Of T)()
End Function

Private Shared Function GetFullList(Of ListType)() _
As List(Of ListType)
Dim returnVal As New List(Of ListType)()
Return returnVal
End Function

Private Shared Function Load(Of ListType)( _
ByVal ds As DataSet) As List(Of DataElement(Of ListType))
Dim returnVal As List(Of DataElement(Of ListType))
returnVal = New List(Of DataElement(Of ListType))
For counter As Int32 = 0 To 5
Dim element As New DataElement(Of ListType)
element = CType(ds.Tables(0).Rows(0)(0), DataElement(Of
ListType))
returnVal.Add(element)
Next
Return returnVal
End Function

End Class

Now, I don't know exactly where you're going with the first 2 functions.
Obviously, to load a list from a DataSet, you need to reference the DataSet
somewhere. The 3rd function takes one as a parameter, and will work fine as
long as the data type in the Table Row is the type that is specified in the
type parameter.

But based on what you've given me so far in the area of requirements (which
is nothing really), that's the best I can do. Hope it gets you on the right
track. Time to take some naproxin sodium!

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
A watched clock never boils.
 
Sorry for the confusion, yes I'm using the Generic List

You keep saying that I don't need inheritance, but I do. What I have is a
Base class called DataElement, which has a bunch of code to do different
things for me automatically. Then I have a lot of classes that inherit from
this and actual concrete implementations adding the rest of the stuff that is
needed for that specific class, such as various properties and other stuff.

Then I have a method outside of the DataElement and the Aor class that deals
with DataElements and needs to load a list of them, which is what was in the
button click event of my example. In this method I'm being passed a
DataElement, but I don't know which type. From this DataElement I need be
able to load a list of this all of the elements and this is where I have the
problem because I need to create a list, but I do not know the type of the
list until runtime.
 
Back
Top