Hi Rory,
<inline>
Rory Becker said:
Hello Bill,
because the list is a List(Of B).
I'm not sure if your example is what was required by the OP. (Perhaps a
mistype?)
Nope, not a mistype.
I would like to be able to ...
...cast a List(Of B) to a List(Of A) (Since all B's contain data
nessecary to qualifiy as an A)
...cast a List(Of C) to a List(Of A) (Since all C's contain data
nessecary to qualifiy as an A)
If you have a List(Of A), you can insert or add items to it that are of type
B or type C, because B and C both derive from A. So soon as you cast a
list(Of B) to a list(Of A) you have removed the type safety, allowing
objects of type C to be added to the list.
Now with a List(Of...) class, this issue isn't that big because the backing
store is an array, and because arrays do allow variance, they have to do
type checking at runtime, so an exception will be thrown. But if you were
to write your own collection class and used a different storage mechanism,
the exception might not occur on add, it might only occur later on read
when, inside your collection class, you try to cast to the desired type.
So variance comes at a cost, and it's for that reason we don't have generic
variance at present.
But would understand not being able to ...
...cast List(Of A) to List(Of B)
...cast List(Of A) to List(Of C)
...cast List(Of C) to List(Of B)
...cast List(Of B) to List(Of C)
While I appreciate that this is not currently allowed, Is this percieved
as something that will arrive in some hypothetical vlanguage variation
down the line, or is there a technical reason why we shouldn't do this?
See above as to the costs. As to will languages go in this direction, yes
I believe so. VB today in 2008 now allows certain types do delegate
variance it didn't allow before. And the CLR itself allows for variance.
The question is how do we surface that in a type safe way that in itself
doesn't become more onerous than the problem we are seeking to solve
Some of the C# team have been blogging about variance in C#.Next (4). If
you look at the complexities that arise from it, it raises the question is
it just simpler to propagate the generic variable instead of requiring the
variance ? For example, given Item_Get is safe, yet Item_Set is not in the
case of casting List(of B) to List(of A), you could imagine defining an
interface that specifies only the Item_Get part and using that, perhaps as a
dynamic interface. In any case, today those thoughts are still "out there",
and in code today in practice the best option is to either use non generic
interfaces or preferably, propagate the generic parameters throughout.