Generics

rbulph

Junior Contributor
Joined
Feb 17, 2003
Messages
397
Is it possible to have a reference to a generic type independent of the Type used for its declaration. e.g:

Code:
Dim r as new List(Of String)
Dim k as List = r   'Editor won't allow this

And if there is a way of doing this, how can you find out what the relevant Type for k is?
 
How would it know exactly what type k should have? What would happen if you wrote code like

Visual Basic:
Dim s as new List(Of String)
Dim i as New List(Of Integer)

Dim k as List = s
k = i  'what happens here?

Also if you are trying to do this at runtime you would effectively have no compile time validation anyway, pretty much the same if you used a non-generic collection.

If you could be assigning different types of generic to this variable then is there a common interface / base class all types support (or could you refactor your code to include one)?

It might help if you could give a bit more detail about what you are trying to do as there may be an easier way.
 
If you could be assigning different types of generic to this variable then is there a common interface / base class all types support (or could you refactor your code to include one)?
QUOTE]

Yes.

Suppose you have a drawing application with a lot of boxes on the screen. Lines can be drawn between them, which can be straight or curved. All the curved lines between two boxes need to be stored together, so that they can be drawn without overlapping, and similarly with the straight lines. You don't want to store any of the lines with the boxes, because each line relates to two boxes, so the choice of which to store it with would be arbitrary. I'd rather store them in separate collections. So here's the sort of code I'd like to write:

Code:
Public Class Form1
    Dim j As List(Of LineCol(Of BasicLine))   'This is not the generic object to which my query relates.

    Friend Sub HandleNewLine(ByVal X As BasicLine, ByVal F As Box, ByVal T As Box)
        For Each i As LineCol(Of BasicLine) In j
            If i.FromBox Is F And i.ToBox Is T And i.GetBasicType Is X.GetType Then 'GetBasicType doesn't exist.
                i.Add(X)
                Exit Sub
            End If
        Next

        'No matching LineCol has been found, so create a new one.
        Dim ty As Type = X.GetType
        Dim w As New LineCol(Of ty) 'Type ty is not defined.
        w.Add(X)
        j.Add(w)

    End Sub

End Class

Friend Class LineCol(Of T As BasicLine)
    Inherits CollectionBase
    Friend FromBox As Box
    Friend ToBox As Box

    Friend Sub Add(ByVal value As T)
        MyBase.List.Add(value)
    End Sub
End Class

Friend Class BasicLine

End Class
Friend Class StraightLine
    Inherits BasicLine
End Class
Friend Class CurvedLine
    Inherits BasicLine
End Class
Friend Class Box

End Class

Clearly there are lots of ways you can work around to get this to work, but if it could work, I think this would be the most elegant way to do it. Do you see what I mean?
 
Out of interest the line
Visual Basic:
Dim j As List(Of LineCol(Of BasicLine))
is defining a list of collections - is that what you really need?

Also you might find your LineCol class easier if it inherits from a generic collection rather than collectionbase (collection base is all object and will incur potential performance overheads as well).

Would it not be easier to move the FromBox and ToBox variables into the BasicLine class rather than as part of the collection - that way you could get away with a single collection that contains all lines without the need for a seperate collection for each box pair...

Even if you keep the existing model could you not either just loop over the collection multiple times once for each line type or loop over the collection once and build a seperate collection for each type of line which you then process in turn.

Another possibility is implement some form of sorting so the list always stores (or at least returns) one type of line before another.
 
Out of interest the line
Visual Basic:
Dim j As List(Of LineCol(Of BasicLine))
is defining a list of collections - is that what you really need?

Yes, I think so. I far prefer that to chucking everything into one big bag and having to do iterations to find the things that I need in it.

Also you might find your LineCol class easier if it inherits from a generic collection rather than collectionbase (collection base is all object and will incur potential performance overheads as well).

If it inherits List(Of BasicLine) (say) then I'm not distinguishing between LineCols that contain CurvedLines and ones that contain StraightLines. If it inherits CollectionBase and is a generic (Of BasicLine) then I can set it up to contain only CurvedLines or StraightLines when I declare it.

Would it not be easier to move the FromBox and ToBox variables into the BasicLine class rather than as part of the collection - that way you could get away with a single collection that contains all lines without the need for a seperate collection for each box pair...

If I have the LineCols, I don't think it would be, because then it's duplicative to store this information with each BasicLine.

Even if you keep the existing model could you not either just loop over the collection multiple times once for each line type or loop over the collection once and build a seperate collection for each type of line which you then process in turn.

Another possibility is implement some form of sorting so the list always stores (or at least returns) one type of line before another.

As I say, there are plenty of ways to work around the issue. Looks as if I have to do so to some extent.
 
Back
Top