Debugging a Linkedlist. How do I find out which node I'm pointing out

robertb_NZ

Well-known member
Joined
May 11, 2010
Messages
146
Location
Auckland, New Zealand
Programming Experience
10+
I am using a LinkedList(OF String) to build up a program. Like sticking post-it's in a book, I keep track of where I want to put further statements by saving nodes: -
        Dim Program As New LinkedList(Of String)
        Dim line As LinkedListNode(Of String) = Program.AddFirst("PROGRAM " & Name & " BATCH;")
        Dim EndInputStats, EndOutputStats, OutputStmts, WriteStmt As LinkedListNode(Of String)
        Input = Genrlxls.Input
        line = Program.AddAfter(line, "COPY " & Input & ";")
        Output = Genrlxls.Output
        line = Program.AddAfter(line, "COPY " & Output & ";")
        '   Generate Structure for Copy-Stats
        line = Program.AddAfter(line, "DEFINE Copy-Stats DATA(")
        line = Program.AddAfter(line, "INPUT GROUP,")
        line = Program.AddAfter(line, "Count INTEGER,")
        line = Program.AddAfter(line, "END GROUP,")
        EndInputStats = line
        line = Program.AddAfter(line, "OUTPUT GROUP,")
        line = Program.AddAfter(line, "Count INTEGER,")
        line = Program.AddAfter(line, "END GROUP;")
        EndOutputStats = line


This all works beautifully: it's very easy to insert data where I want with (for example)
Program.Addbefore(EndInputStats, "Counter1 SMALLINT,");

PROVIDED that I use the correct node and don't mess up my logic! Of course I HAVE messed up my logic :blue:, and so I'm trying to debug it. I need to know where the saved marker nodes (like EndInputStats) are pointing. I wrote a little diagnostic routine: -
    Sub DebugProgram(Program As LinkedList(Of String), OutputStmts As LinkedListNode(Of String))
        Dim Comment As String
        For IX = 0 To Program.Count
            If OutputStmts.Equals(Program(IX)) Then
                Comment = "<= OutputStmts"
            Else
                Comment = ""
            End If
            Debug.Print(Program(IX) & Comment)
        Next
    End Sub


But Comment stays stubbornly blank. I tried
If OutputStmts IS Program(IX)

This doesn't help. (reasons were obvious when I thought about it). I tried changing the loop to
For Each LLN As LinkedListNode(Of String) In Program

but this won't compile, throwing message
Value of type 'String' cannot be converted to 'System.Collections.Generic.LinkedListNode(Of String)'.

I can't find any property of LinkedListNode(OF String) that tell me its LinkedList index, nor a way to return a LinkedListNode from Program so that I could use IS. To make any of the comparisons work I have to use the node's value, but this gives me the string value and even if this, Previous, and Next nodes all have the same string values as Program (IX), Program(IX-1), and Program(IX+1) this does not prove that the node IS Program(IX).

Can somebody tell me the answer? Thank you, Robert.
 
Last edited by a moderator:
The whole point of a LinkedList(Of T) is the fact that it's linked. If you want to traverse a LinkedList(Of T) then you use the links. The First property of the LinkedList(Of T) gives you the first node, i.e. the first LinkedListNode(Of T) in the LinkedList(Of T). You then call Next on that node to get the next node. You keep doing that until Next returns Nothing, which means that you've reached the end of the list. E.g.
Dim node = myLinkedList.First()

Do Until node Is Nothing
    'Use node here.

    node = node.Next()
Loop
If you've read the documentation then you know that a LinkedList(Of T) implements IEnumerable(Of T), not IEnumerable(Of LinkedListNode(Of T)). That means that a For Each loop over the list will give you the Value of each node, not each node itself.
 
Thank you, I'd missed the subtlety that if you iterate the list with DO UNTIL/Node.Next you get a LinkedListNode, whereas if you iterate it with FOR EACH or FOR index = ... you get the node values. My debugging code now works perfectly with
Sub DebugProgram(Program As LinkedList(Of String), OutputStmts As LinkedListNode(Of String))
' Debugging routine
Dim Comment As String
Dim node As LinkedListNode(Of String) = Program.First()
Do Until node Is Nothing
'Use node here.
If node Is OutputStmts Then
Comment = "<= OutputStmts"​
Else
Comment = ""​
End If
Debug.Print(node.Value & Comment)
node = node.Next()​
Loop​
End Sub​

Given that For index = ... also traverse the list by link, I find it surprising that Microsoft hasn't provided a way of getting to the LinkedListNode(OF String) with these loops.

By the way, am I correct to believe that it is good practice to specify the object type whenever possible? I follow this practice, but I'm not sure how important it is or whether it's a legacy of my background.
 
Given that For index = ... also traverse the list by link, I find it surprising that Microsoft hasn't provided a way of getting to the LinkedListNode(OF String) with these loops.
I don't think so. Just like the point of a List(Of String) is to store Strings, so it is for a LinkedList(Of String). That's why LinkedList(Of String) implements IEnumerable(Of String) rather than IEnumerable(Of LinkedListNode(Of String)). If the point of the list is to store Strings then it makes perfect sense that enumerating it yields Strings. It doesn't implement IList(Of String) though, which again makes perfect sense because a linked list is about links, not about indexes.
By the way, am I correct to believe that it is good practice to specify the object type whenever possible? I follow this practice, but I'm not sure how important it is or whether it's a legacy of my background.
Type inference was introduced to support anonymous types in LINQ and that's the only place you have to use it. I started using type inference only where it was glaringly obvious what the type was but I've found myself considering over time that more instances are obvious enough. If I write a code example where the type is not obvious then I'll specify it but, in my own code, where I can simply mouse over a variable to see what type it is, I tend to use type inference most of the time. What you do is up to you.
 
If you care about indexes then you really shouldn't be using a linked list in the first place. A List(Of T) does allow you to insert at any position, but it's not as efficient as inserting into a LinkedList(Of T). If your list is fairly small and not being inserted into very much though, that's no big deal. A LinkedList will only be a genuine advantage when you have lots of inserts being done.
 
Back
Top