Generic Linked List

S

Scott Stark

Hello,

The code below represents a singly-linked list that accepts any type of
object.

You can see I'm represting the Data variable a System.Object. How would I
update this code to use generics instead of System.Object. I want the code
in Form1_Load to remain exactly the same, but in the background I want to
use generics. I'm trying to get a better understanding of how it works and
I'm a little stuck.

I tried converting the LinkedListItem class to: Public Class
LinkedListItem(Of T) and then, of course switching the System.Object
variables to type T. But then in the LinkedList class, my _Head and _Tail
objects would need to be case as LinkedListItem(Of T), but at that point it
needs to know the object type (String, Integer, Double, etc). I won't know
the object type until I've added it to the list using my Add() method. I'm
sure it's a simple solution, I'm just stuck on this one.

Thanks in advance.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Dim MyList As New LinkedList
MyList.Add("12345")
MyList.Add(55)
MyList.Add("Kathy")
MyList.Add(1.234)
End Sub

Public Class LinkedList
Private _Head As LinkedListItem
Private _Tail As LinkedListItem

Public ReadOnly Property GetFirstItem()
Get
Return _Head
End Get
End Property

Public Property Head() As LinkedListItem
Get
Return _Head
End Get
Set(ByVal value As LinkedListItem)
_Head = value
End Set
End Property

Public Sub Add(ByVal Data As Object)
Dim Item As New LinkedListItem(Data)

If (_Head Is Nothing) Then
_Head = Item
End If

If (_Tail Is Nothing) Then
_Tail = Item
Else
_Tail.NextItem = Item
_Tail = Item
End If
End Sub
End Class

Public Class LinkedListItem
Private _Data As Object
Private _NextLink As LinkedListItem

Public Property Value() As Object
Get
Return _Data
End Get
Set(ByVal value As Object)
_Data = value
End Set
End Property

Public Property NextItem() As LinkedListItem
Get
Return _NextLink
End Get
Set(ByVal value As LinkedListItem)
_NextLink = value
End Set
End Property

Public Sub New(ByVal Data As Object)
_Data = Data
End Sub
End Class
 
S

Scott Stark

Ok, I'm continuing to try this on my own. Here's what I have. It won't
compile yet so I'm not sure if I'm on the right track, but I thought I'd
keep giving it a shot. There are no error indications in my Form1_Load or my
LinkedListItem class.

My problem is in the LinkedList class (which hasn't been changed since the
last post).

Private _Head As LinkedListItem <--- This has to have a type declaration
(i.e. LinkedListItem(Of String)). At this point, the program doesn't know
what type will be passed. Where am I going wrong?

Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Dim MyList As New LinkedList
MyList.Add(New LinkedListItem(Of String)("12345"))
MyList.Add(New LinkedListItem(Of Integer)(55))
MyList.Add(New LinkedListItem(Of String)("Some words"))
MyList.Add(New LinkedListItem(Of Double)(1.234))

Dim i = MyList.GetFirstItem

Do While Not i Is Nothing
TextBox1.Text += i.Value & vbCrLf
i = i.NextItem
Loop
End Sub
End Class

Public Class LinkedList
Private _Head As LinkedListItem
Private _Tail As LinkedListItem

Public ReadOnly Property GetFirstItem()
Get
Return _Head
End Get
End Property

Public Property Head() As LinkedListItem
Get
Return _Head
End Get
Set(ByVal value As LinkedListItem)
_Head = value
End Set
End Property

Public Sub Add(ByVal Data As Object)
Dim Item As New LinkedListItem(Data)

If (_Head Is Nothing) Then
_Head = Item
End If

If (_Tail Is Nothing) Then
_Tail = Item
Else
_Tail.NextItem = Item
_Tail = Item
End If
End Sub
End Class

Public Class LinkedListItem(Of T)
Private _Data As T
Private _NextLink As LinkedListItem(Of T)

Public Property Value() As T
Get
Return _Data
End Get
Set(ByVal value As T)
_Data = value
End Set
End Property

Public Property NextItem() As LinkedListItem(Of T)
Get
Return _NextLink
End Get
Set(ByVal value As LinkedListItem(Of T))
_NextLink = value
End Set
End Property

Public Sub New(ByVal Data As T)
_Data = Data
End Sub
End Class
 
C

Cor Ligthert[MVP]

Scott,

This is asked a thousand times to show that you can only use scripting and
that early binding is a fake.

However what kind of application are you building that you don't know which
values types are used.

Strongly typed means that the value type is known before runtime starts.

However, as you want this, then use reflection, thousand of persons have
been before you going this way, with the same result: The were using
strongly typed at the time they understood it.

Cor
 
S

Scott Stark

Actually, it's an exercise in Chapter 1 of the prep book for the MCTS 70-536
exam.

"Create a linked-list generic class that enables you to create a chain of
different object types."

I've been trying to accomplish this on my own for about three days and have
finally decided to ask for help moving in the right direction. I've gotten
all of the other "Suggested Practices" down, just not this one. Given that
it's in Chapter 1 and they haven't even touched on reflection yet, I'm
assuming there's a simpler way to do it.
 
C

Cor Ligthert[MVP]

Scott,

I don't have that book at hand now, I will see as nobody has answered if I
find your problem at monday.

Cor
 
B

Bill McCarthy

Hi Scott,
My problem is in the LinkedList class (which hasn't been changed since the
last post).

Private _Head As LinkedListItem <--- This has to have a type declaration
(i.e. LinkedListItem(Of String)). At this point, the program doesn't know
what type will be passed. Where am I going wrong?

There's two typical design patterns used for this:

The first, and most common is for the LinkedList to be generic,
LinkedList(Of T) and each item to be a LinkedListItem(Of T). In your case
however you are using different types, so the generic would need to be
instantiated as LinkedList(Of Object) and LinkedListItem(Of Object), which
is seldom of any value ;)

The other kind of pattern you can use is an interface or an abstract base
class, eg:

Public MustIntherit CLass LinkedListItem
Private _NextLink As LinkedListItem

Public Property NextItem() As LinkedListItem
Get
Return _NextLink
End Get
Set(ByVal value As LinkedListItem(Of T))
_NextLink = value
End Set
End Property

End CLass


Public Class LinkedListItem(Of T)
Inherits LinkedListItem

Private _Data As T

Public Property Value() As T
Get
Return _Data
End Get
Set(ByVal value As T)
_Data = value
End Set
End Property

Public Sub New(ByVal Data As T)
_Data = Data
End Sub
End Class


Although that may work, again you will have an issue actually getting the
data from the linked list as you would need to know the generic type before
hand, which makes it kind of useless in practice. You could have a
MustOverride property Data As Object, but then you have gone full circle,
and back to object. And reality is, that is the crux of your problem. you
have different types and their only common base is Object, so generics isn't
really a solution in those cases.

BTW: I strongly suggest you turn Option Strict On.
 
S

Scott Stark

Hi Bill,

That was basically the problem I was running into. I can just cast the type
to Object, but then I might as well just not use generics, as you said.

I told the other poster that I'm doing this as an exercise in Chapter 1 of
the prep book for the MCTS 70-536 exam. Specifically, the question states:

"Create a linked-list generic class that enables you to create a chain of
different object types."

I'm at a total loss as to how to accomplish this without incuring boxing and
unboxing penalties by using Object, which seems to defeat the purpose of
this exercise in generics...
 
B

Bill McCarthy

Hi Scott,

Scott Stark said:
Hi Bill,

That was basically the problem I was running into. I can just cast the
type to Object, but then I might as well just not use generics, as you
said.

I told the other poster that I'm doing this as an exercise in Chapter 1 of
the prep book for the MCTS 70-536 exam. Specifically, the question states:

"Create a linked-list generic class that enables you to create a chain of
different object types."

I'm guessing, but sounds like they worded that poorly. I think they just
want you to create a generic linked list where all the members are of the
same type and access to them is strongly typed. I think what they were
trying to do was explain that the generic type allows you to specify
different types, but each instantiation of the linked list has only one type
for it's items


I'm at a total loss as to how to accomplish this without incuring boxing
and unboxing penalties by using Object, which seems to defeat the purpose
of this exercise in generics...


FWIW: You'll only get boxing with value types. But the real benefit of
generics, especially when you have Option Strict On, is you have strongly
typed access which allows for greater design time feedback and compile time
type checking.
 
S

Scott Stark

It's supposed to be an exercise in generics, and keep in mind it's from the
very first chapter in the book so it's probably supposed to be relatively
simple.
Dim A As LinkList(Of String)
Dim B As LinkList(Of Integer)

This, I've got down. Pretty straightforward, simplistic approach. I also am
starting to believe this is all they are asking for, in which case I wasted
a whole lot of time, LOL.
2. (not real Generics, but a general purpose, or "generic", linked list)
Create a linked-list class that enables you to create a chain of objects
of mixed type, by handling all objects as type Object.

I also have a linked list class written to do just this. My interpretation
of the question was that they wanted a combination of the two apporaches,
something like:

Dim A As LinkList(Of T) (which i know is not syntactically correct)
A.Add(1.234)
A.Add("Some words"
A.Add(New MailMessage())

Etc...

Doesn't seem that this is possible without casting everything as an Object,
which was my initial trouble spot. I think the question is just a bit
misleading.
 
C

Cor Ligthert [MVP]

Scott,

I assume that you confusing the the class using non generics showed on page
40 with the class using the generics.

In my idea are in the generic sample the types T and U used, however not
described what they are, but it are types, not raw objects.

Cor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top