Array initialization with common base - Best way?

Ary Borenszweig ary at esperanto.org.ar
Mon Nov 10 04:32:48 PST 2008


Ary Borenszweig wrote:
> deadimp escribió:
>> That's the problem I had mentioned, though - the type of the entire 
>> array being inferred from the first element rather than the context 
>> (i.e. what it's initializing if not declared as 'auto') or subsequent 
>> elements (which would be a bit difficult...).
>> When I try that, the compiler prints this error message: (formatted 
>> for this context)
>> "Error: cannot implicitly convert expression (new BadChild) of type 
>> BadChild to GoodChild"
>>
>> I'm not sure what a good syntax replacement would be. C# / Java style 
>> new array instantiations wouldn't really fit in syntactically with the 
>> already established style of arrays. But maybe there's a way the type 
>> of an array coud be explicitly stated without having to cast to make 
>> the type inference correct.
>>
>>
>> Jérôme M. Berger Wrote:
>>
>>>     I would replace the last line with:
>>> Base[] list = [ new GoodChild, new BadChild, ...];
>>>
>>>     It's clearer, there's less typing and it won't suddenly fail if you
>>> remove the first element and accidentally remove the cast at the
>>> same time or if you add a new first element and forget to add the
>>> cast...
>>>
>>>         Jerome
> 
> Can't the compiler try to set the array's component type to the most 
> general type of it's elements, by combining the most general types by 
> pairs?
> 
> Hmmm... now that I think it, it's not that easy because of interfaces. 
> Did this subject was ever discussed? If not, I'll try to think of an 
> algorithm for this. (because if it was discussed, there must be a good 
> reason for not doing this)

Ok, I wanted to see what does C# do with this. C# has the "var" keyword
that has the same semantic as "auto". Also, it has array initializers,
and today I found they come in two flavors:

{ x, y, z }        --> don't use type inference
new [] { x, y, z } --> use type inference

I can see the type of a "var" variable by hovering over it in Visual
Studio. Let's see:

var x = { 1, 2, 3 };
         // Error: cannot initialize an implicitly-typed
         // local variable with an array initializer

var x = new [] { 1, 2, 3 };    // ok, x is Int32[]
var x = new [] { 1, 2.0, 3 };  // ok, x is Double[]

Now with classes (object is root of all classes).

class A { }

class B { }

var x = new [] { new object(), new A() };  // ok, x is Object[]

var x = new [] { new A(), new B() };
         // Error: no base type for implicitly typed array

(the question here is, why not infer object[]?)

Without type deduction:

object[] x = new [] { new A(), new B() };
         // Error: no base type for implicitly typed array

But, without new []:

object[] x = { new A(), new B() }; // ok

In this last example, although no type can be inferred for the array
initializer, the compiler can see that each of it's elements can be cast
to object, and so doesn't give a compile error.

Why not implement this last behavior in D? I think this is a very common
case, and it seems easy to implement. I'll try to debug DMD's source 
code at night to see what can be changed for this to work... if there's 
interest.


More information about the Digitalmars-d-learn mailing list