Generics and inheritance

M

Marina

Hi,

Let's say I have 2 classes, one of which is inheriting from the other.
I also have a generic class.
When I declare an instance of the generic class, I want to be able to cast a
generic declaration of the child class as the base class.

I have an example below, and the last line in TestSub does not compile.
Since Class2 IS a Class1, I want to be able to make that assignment, and
treat my collection of Class2 objects as Class1 objects if I want, since
after all, that is what they are.

How do I go about making this work? Is it event possible?

Public Class Class1
End Class

Public Class Class2
Inherits Class1
End Class

Public Class CollectionClass(Of someType)
End Class

Public Class TestClass
Public Sub TestSub()
Dim t1 As CollectionClass(Of Class1)
Dim t2 As New CollectionClass(Of Class2)

t1 = t2
End Sub
End Class
 
H

Herfried K. Wagner [MVP]

Marina said:
Let's say I have 2 classes, one of which is inheriting from the other.
I also have a generic class.
When I declare an instance of the generic class, I want to be able to cast
a generic declaration of the child class as the base class.
[...] How do I go about making this work? Is it event possible?

That's not possible. There is no subtype-relationship between 'Foo(Of
Derived)' and 'Foo(Of Base)'.
 
M

Marina

Why not? Anything you can do to Foo(of Derived) in a generic manner, you can
do to Foo(Of Base)

Even if the collection is declared as CollectionClass(Of someType As Base),
this still does not compile. In this case, it would be guaranteed that only
Base and its children can be instantiated. If I have an instance of
Derived, I can treat it as a Base. So if I have a Foo(Of Derived), why can't
I treat it as Foo(Of Base)?

Herfried K. Wagner said:
Marina said:
Let's say I have 2 classes, one of which is inheriting from the other.
I also have a generic class.
When I declare an instance of the generic class, I want to be able to
cast a generic declaration of the child class as the base class.
[...] How do I go about making this work? Is it event possible?

That's not possible. There is no subtype-relationship between 'Foo(Of
Derived)' and 'Foo(Of Base)'.
 
H

Herfried K. Wagner [MVP]

Marina,

Marina said:
Why not? Anything you can do to Foo(of Derived) in a generic manner, you
can do to Foo(Of Base)

Even if the collection is declared as CollectionClass(Of someType As
Base), this still does not compile. In this case, it would be guaranteed
that only Base and its children can be instantiated. If I have an
instance of Derived, I can treat it as a Base. So if I have a Foo(Of
Derived), why can't I treat it as Foo(Of Base)?

I do not know the exact reasons for this behavior, but has clearly been a
design decision.

However, note that 'BaseCollection(Of Class1)' is the base type of
'DerivedCollection(Of Class1)' if 'DerivedCollection(Of T)' inherits from
'BaseCollection(Of T)'.
 
M

Mattias Sjögren

Why not? Anything you can do to Foo(of Derived) in a generic manner, you can
do to Foo(Of Base)

But not the other way around, i.e. there are things you can do with
your Foo(Of Base) that shouldn't be allowed for a Foo(Of Derived). To
continue your example, imagine if you write

Public Sub TestSub()
Dim t1 As CollectionClass(Of Class1)
Dim t2 As New CollectionClass(Of Class2)

t1 = t2
t1.Add(New Class1)
End Sub

Adding a Class1 instance to a Class2 collection is clearly a no no but
the code would compile and you'd get a runtime error instead. That
would go against one of the major benefits with generics - to get
improved compile time type safety.


Mattias
 
M

Marina

Ok, fair point.

However, it would be awfully nice to have strongly typed collection classes
that can be cast back and forth the same way.

In reality, I want to have a Class1Collection and a Class2Collection where
each one is coded to return the corresponding class type, but where
Class2Collection is derived from Class1Collection. Right now it's a lot of
repetitive code with shadowed properties and such, and I was hoping generics
would be the way to eliminate all that repetition.
 
J

Jay B. Harlow [MVP - Outlook]

| Why not? Anything you can do to Foo(of Derived) in a generic manner, you
can
| do to Foo(Of Base)
Rick Byers goes into more details on the reason Mattias gave:

http://blogs.msdn.com/rmbyers/archive/2005/02/16/375079.aspx

--
Hope this helps
Jay [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


| Why not? Anything you can do to Foo(of Derived) in a generic manner, you
can
| do to Foo(Of Base)
|
| Even if the collection is declared as CollectionClass(Of someType As
Base),
| this still does not compile. In this case, it would be guaranteed that
only
| Base and its children can be instantiated. If I have an instance of
| Derived, I can treat it as a Base. So if I have a Foo(Of Derived), why
can't
| I treat it as Foo(Of Base)?
|
| | >> Let's say I have 2 classes, one of which is inheriting from the other.
| >> I also have a generic class.
| >> When I declare an instance of the generic class, I want to be able to
| >> cast a generic declaration of the child class as the base class.
| >> [...] How do I go about making this work? Is it event possible?
| >
| > That's not possible. There is no subtype-relationship between 'Foo(Of
| > Derived)' and 'Foo(Of Base)'.
| >
| > --
| > M S Herfried K. Wagner
| > M V P <URL:http://dotnet.mvps.org/>
| > V B <URL:http://classicvb.org/petition/>
|
|
 

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