about collection and template variable

Hi:

I am using Visual Basic.Net 2005 and Framework 2.0.

Now I design a class as following:

public class para(of T)

dim ab as integer

dim content as T

end class

and also I have another class

public class equipment

dim id as integer

dim name as string

public paracol as New System.Collection.Generic.list(of Para)

end class

Here, I have a problem. Because my class para includes a template type T, when i create a collection, I can't do that Anybody knows how to do that Thank you very much!




Answer this question

about collection and template variable

  • J A Y

    I have the exact same problem. I have a type that fits the criteria for a generic through and through. In my case, digesting engineering data:

    Public Class Measurement(Of T As Structure)

    ...

    Private m_Data As T

    Private m_Name As String

    Public Property Value As T

    ...

    End Property

    Public Property Name As String

    ...

    End Property

    ...

    End Class

    And now I want a collection of those objects associated by their name, so it makes it a little easier to get to later:

    Public Class MeasurementList

    Inherits Dictionary(Of String, Measurement(Of T))

    ...

    End Class

    Just let me say at this point, I know there are a lot of ways to skin this cat. I know I can use Object to solve the problem in the Measurement class. As a matter of a fact, that's what I did do (did do ). Anyway, like Spanky "I'll eat it but I won't like it."

    What I'm saying is I just hate I can't do this. To me, the MeasurementList class should automatically obey the constraint put on the Measurement class and accept any Measurement. I would think internally you could make the collection of other generics track only the pointers to the Measurement classes that successfully compiled. So then I could do something like what the guy above wants to do:

    Dim measurement1 As Measurement(Of System.DataTime)

    Dim measurement1 As Measurement(Of System.UInt32)

    ' etc

    Dim measurementList As MeasurementList()

    measurementList.Add( measurement1.Name, measurement1 )

    measurementList.Add( measurement2.Name, measurement2 )

    ' etc

    Please Microsoft coding gurus, if you hear me, please try to make this so! At least give us something like this capability! I could live with the requirement that the generic going into the collection of generics must have some type of constraint on it, has to be a class and not a structure, or it has to contain the word "HocusPocus" in the class name.

    I’m going to wish on every shooting star I see for the next three months…



  • ShaulB

    hi, Johan Stenberg:

    Thank you for your helps and explaination.

    Now I have another question, actually, as you said, I think I only get the collection with one kind of variable. for example

    public class equipment(Of T)
    dim id as integer
    dim name as string

    public paracol as New System.Collection.Generic.list(of Para(Of T))
    end class

    dim at as new equipment(of string)

    which means I only get paracol collection with string type, but if I would like to get such different types of paracol in one equipments what can I do

    for example:

    dim para1 as new para(of string)

    dim para2 as new para(of integer)

    dim at as new equipment

    equipment.paracol.add(para1)

    equipment.paracol.add(para2)

    I konw I have one solution that is I don't make restriction for paracol, if I use :

    dim paracol as new collection

    it will fix this problem, however, I have another limitation because I can't limit paracol that only includes user-defined type Para, in other words, I can add any kind of variable into paracol collection.

    Thank you very much!



  • Olmy

    Well, either you know what type you are going to use as the type parameter in the equipment class, in which case your public paracol declaration can use that:

    public paracol as New System.Collection.Generic.list(of Para(Of Whatever))

    If you don't know what type your are going to use, then you can make the equipment class into a generic class:

    public class equipment(Of T)
    dim id as integer
    dim name as string

    public paracol as New System.Collection.Generic.list(of Para(Of T))
    end class

    Best regards,
    Johan Stenberg



  • imkow

    Hi, Johan Stenberg:

    Thank you for your solution so much!



  • Willbu

    Hi, Johan Stenberg:

    Thank you for your explanation again, and I am sorry that I don't understand the second answer. Now I write my question clearly.

    public class Para(Of T)

    dim ab as string

    dim value as T

    end class

    public class equipment

    dim id as integer

    public paracol as new System.Collections.Generic.List(Of Para(Of T))

    end class

    I hope I can do this way, I give you a example

    dim a1 as new para(of string)

    dim a2 as new para(of integer)

    dim at as new equipment

    at.paracol.add(a1)

    at.paracol.add(a2)

    Could you give me more explaination about that Thank you very much!



  • Marcel Marnix

    Para(Of String) and Para(Of Integer) are totally different types. The way that your code is written, the paracol list would have to be of type System.Collections.Generic.List(Of Object) since that is the base class for Para(Of String) and Para(Of Integer).

    What I suggested was to do something like this:

    ''' <summary>

    ''' Base class that contains all the common information (things that you were able to do

    ''' for all Para(Of T) objects)

    ''' </summary>

    ''' <remarks></remarks>

    Public Class ParaBase

    ' Change to protected so derived classes can get access. Best practice

    ' would suggest making into a property...

    Protected ab As String

    ' Field backing property

    Private m_value As Object

    ''' <summary>

    ''' I have changed the Value field to a property so that I can change it's implementation

    ''' below

    ''' </summary>

    ''' <value></value>

    ''' <returns></returns>

    ''' <remarks></remarks>

    Public Property Value() As Object

    Get

    Return m_value

    End Get

    Set(ByVal value As Object)

    m_value = value

    End Set

    End Property

    End Class

    Public Class Para(Of T)

    Inherits ParaBase

    ' I'm shadowing the base class's Value property to return

    ' the correct type.

    Public Shadows Property Value() As T

    Get

    Return DirectCast(MyBase.Value, T)

    End Get

    Set(ByVal value As T)

    MyBase.Value = value

    End Set

    End Property

    End Class

    Public Class equipment

    Dim id As Integer

    ' This should most likely also be made into a property

    Public paracol As New System.Collections.Generic.List(Of ParaBase)

    End Class

    Best regards,
    Johan Stenberg



  • Richard Chenglo

    The first question that I'd ask here is why Para is a generic class If you want to be able to put Para(Of Integer) and Para(Of String) in the same collection, the collection has to be able to accept objects of the first common ancestor of those two classes, which would be the base class of Para(Of T) - and if they don't have an explicit base class, they would implicitly inherit from System.Object...

    What I suspect that you want to do here is to factor out all of the methods that are independent of T from the Para class into separate class (ParaBase) and have Para(Of T) inherit from that. Once you have done that, you can restrict the type parameter of your Equipment class to only accept types of that base class:

    Public Class Equipment(Of T As ParaBase)

    ...

    End Class

    Best regards,

    Johan Stenberg



  • about collection and template variable