SubClass[] does not implicitly convert to SuperClass[], why?

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Feb 20 02:40:53 PST 2015


On Friday, February 20, 2015 08:25:48 rumbu via Digitalmars-d-learn wrote:
> On Friday, 20 February 2015 at 07:57:17 UTC, Tobias Pankrath
> wrote:
> > What's the reason behind this design?
> >
> > class Super {}
> > class Sub : Super {}
> >
> > void foo(Super[] sup) {}
> >
> > void main() {
> >     Sub[] array;
> >     foo(array); // error, cannot call foo(Super[]) with
> > arguments (Sub[])
> > }
>
> Just make the sup parameter const:
>
> void foo(in Super[] sup) {}
>
> http://dlang.org/arrays.html (end of the page):
>
> A dynamic array T[] can be implicitly converted to one of the
> following:
> const(U)[]
> const(U[])
> Where U is a base class of T.
>
> The reson behind the design - I wonder about that also.

Well, if it were legal, you could do something like

class Super {}
class Sub : Super {}
class Sub2 : Super {}

Sub[] subArr = createSubArr();
Super[] superArr = subArr;
superArr[2] = new Sub2;

Now, all of a sudden, subArr[2] is a Sub2, when a Sub2 is not a Sub. So, you
would have broken the type system. The issue is called array covariance.
const avoids the problem, because you can't assign any of the elements of
the array.

A similar question was asked an answered previously on SO:

http://stackoverflow.com/questions/18158106/array-of-concrete-class-not-covariant-with-array-of-interface

though it looks like at the time that the questioned was answered, the
conversion didn't work with const, so things have improved since then. But
it should never work with mutable arrays or the type system would be
violated.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list