Generic Types Question

A

Angel Mateos

I have this structure:

Class ElemBase

Class Elem1 : Inherits ElemBase

Class ColecBase(Of GenElem As {ElemBase, New}) : Inherits
System.ComponentModel.BindingList(Of GenElem)

Class Colec1 : Inherits ColecBase(Of Elem1)

Class Class1

Public E As ElemBase

Public C As ColecBase(Of ElemBase)

End Class

Class Class2

Dim ColH As Colec1

Dim Cl1 As Class1

Sub proc()

Cl1.C = ColH

End Sub

End Class

I get an error in sub proc because Colect1 can't be converted to
ColecBase(of ElemBase)

there is a way to do this?
 
B

Branco Medeiros

Angel said:
I have this structure:

Class ElemBase

Class Elem1 : Inherits ElemBase

Class ColecBase(Of GenElem As {ElemBase, New}) : Inherits
System.ComponentModel.BindingList(Of GenElem)

Class Colec1 : Inherits ColecBase(Of Elem1)

Class Class1

Public E As ElemBase

Public C As ColecBase(Of ElemBase)

End Class

Class Class2

Dim ColH As Colec1

Dim Cl1 As Class1

Sub proc()

Cl1.C = ColH

End Sub

End Class

I get an error in sub proc because Colect1 can't be converted to
ColecBase(of ElemBase)

there is a way to do this?

The important thing to notice is that generic instanciations don't keep
the inheritance chain of the type arguments (in other words, a generic
collection(of integer) doesn't inherit from a generic collection(of
object), even though ints do inherit from objects).

You are getting the error because you're assigning an incompatible
type: Class Colec1 is a collection of Elem1, not a collection of
ElemBase, as Class1.C expects. Even though Elem1 inherits from
ElemBase, the Colec1 class can only deal with the specific type Elem1,
while Class1.C requires a collection that accepts any ElemBase
inheritance, a contract that a Colec1 can't honor.

Suppose the compiler "didn't see" the error of the construction and let
you assign ColH to Col1.C, as you intended.

This means that you'd be able to compile the following erroneous code:

Dim Bad As New ElemBase '<-- this is no Elem1
Cl1.C.Add(Bad) '<-- Oops!

Maybe a way to achieve what you want is to provide a common interface
to all ColecBase instanciations, say, ICollection(of ElemBase), where
you can explicitly cast the provided ElemBase to the instanciated
GenElem type:

<aircode>
Class ColecBase(Of GenElem As {ElemBase, New})
Inherits System.ComponentModel.BindingList(Of GenElem)
Implements ICollection(Of ElemBase)

Private Sub ICollection_Add(ByVal item As ElemBase) _
Implements System.Collections.Generic.ICollection(Of ElemBase).Add
'This may throw an invalid cast at run time!
Me.Add(CType(item, GenElem))
End Sub

'...
End Class

Class Class1
Public E As ElemBase
Public C As ICollection(Of ElemBase)
End Class

</aircode>

Notice, however, that such castings is the problem generics came to
solve. Maybe a revision of your requirements is in order... =P

HTH.

Regards,

Branco.
 

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