Container Contravariance was Re: [typing] Type-erasure re generics

Jonathan M Davis jmdavisProg at gmx.com
Wed Sep 29 11:35:09 PDT 2010


On Wednesday, September 29, 2010 11:20:11 Jesse Phillips wrote:
> Jesse Phillips Wrote:
> > I will first quote Wikipedia about C#[1]:
> > 
> > "For example, in C# 3.0 generic parameters did not support co or
> > contravariance; List<A> was not equivalent to List<TypeDerivedFromTypeA>
> > as one might intuit; however, this is now supported in C# 4.0, though
> > standard arrays have always supported covariance & contravariance since
> > .NET was introduced."
> > 
> > Then I will show an example that does compile[2]:
> > 
> > void main() {
> > 
> >     A[] = [new B(), new A()];
> > 
> > }
> > 
> > 1.
> > http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_sci
> > ence) 2. http://ideone.com/ZzDTs
> 
> Actually my example code should have been this[1]:
> 
> class A {}
> class B:A {}
> 
> void main() {
>     A[] a = new B[6];
> }
> 
> 
> 1. http://ideone.com/Q59iD

Pelle's point still stands.

a[0] = new A();

would be legal code if you could assign a B[] to an A[], and since an A isn't 
necessarily a B, that doesn't work at all. If the underlying type were actually 
A[], then it would be fine to use varying types derived from A, but since the 
underlying type would actually be B[], it would break B[] to put anything in it 
which wasn't a B or a type derived from B.

Now, const A[] might work, since then you couldn't assign any of its values and 
any B in a B[] is obviously an A. So, I could see passing B[] to function that 
took a const A[] as working (though maybe there's something that I'm missing 
that would make that not work), but you can't assign a B[] to a mutable A[] or 
your going to be able to put the wrong type in the underlying B[].

- Jonathan M Davis


More information about the Digitalmars-d mailing list