Using an object from a Generically defined class as a variable.

G

Guest

I have the following base class that uses Generics in its definition.

MyList(of T, C) - T is a BindingList(Of C), C is the type
in the list

I have many implemented classes that use this definition...

Class A ( of A, C)
Class B(of B,C) and so on.

Now I want to write a class that has a variable to which ANY of the derived
classes
of MyList(of T,C) can be assigned.

What is the syntax? When I try to tell the system that the type of the
variable is "MyList" it proceeds assuming that I'm making a derivative class
and wants me
to specify what types "T" and "C" are.

How do I do this?

Thanks.
 
L

Larry Lard

BBM said:
I have the following base class that uses Generics in its definition.

MyList(of T, C) - T is a BindingList(Of C), C is the type
in the list

I have many implemented classes that use this definition...

Class A ( of A, C)
Class B(of B,C) and so on.

Now I want to write a class that has a variable to which ANY of the derived
classes
of MyList(of T,C) can be assigned.

What is the syntax?

This doesn't work the way you want. To use an example from the
framework - consider List(Of T). You want to be able to write

Class Foo
Private L As ...

where Foo.L can be assigned any particular List(Of something), so we
could assign to Foo.L a List(Of String), a List(Of Integer), and so on.
But remember that generics are all about providing compile-time type
safety: so what could we possibly do with Foo.L? We couldn't say
L.Add(x), because the compiler wouldn't be able to verify that x was
typesafe to be added to this particular List(Of something). We couldn't
pull an item out of L, because the compiler wouldn't know what type it
was.

The principle here is that the constructed classes are *not* 'derived'
from a generic 'base class' - this is a different mechanism from
inheritance. There _is_ no base class.

So what can we do? There are two things:

1) If we want to just pass instances of the constructed classes around,
knowing that we can't type-safely dig into them, we can define an
interface that exposes that behavior we will want at runtime, and have
the generic class implement this interface. For example, List(Of T)
implements IList, so a List(Of String) and a List(Of Integer) could
both be assigned to

Private L As IList

Note that all we can say about L is that it contains Objects: we cannot
safely add items to it, nor assume the type of objects we pull out of
it.

So in your case you would define

Interface IMyList

then have MyList(Of T,C) implement this interface. Bear in mind that
IMyList is not generic, and can't expose generic types (so you can't
have IMyList.Add(item As C), for example).

2) If you are going to have a class that contains a member with a
generic type, and you want type-safe access to this member, then the
containing class needs to be a generic type itself, with appropriate
constraints.

So you already have

Class MyList(Of T As BindingList(Of C), C)

and you want a type that contains a MyList, so you would say:

Class ContainsList(Of T As BindingList(Of C), C)

Private list As MyList(Of T, C)

End Class

This of course means that ContainsList is 'tied' by type to the
particular MyList it contains - your message suggests you might want to
arbitrarily associate different MyList's to any ContainsList, in which
case the interface option is better - but you lose compile-time type
safety.
 
G

Guest

Thanks for the detailed explanation. I had stumbled upon the second approach
myself (the "ContainsList" approach), but I was having trouble working
through the syntax. My actual situation is slightly more complex than your
example, but I was able to use your code as a template and get mine to work.

Thanks for your help!

BBM
 

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