Multiple return type from object factory possible?

2013-06-22 Thread deed

class A  { ... }
class NonContainer : A   { ... }
class Container : A  { A[] container; }
class NC1 : NonContainer {}
...
class C1 : Container {}
...

A getO(string info)
{
switch (info)
{
default : return new NonContainer();
case info1: return new C1();
case info2: return new NC1();
case info3: return new Container();
case info4: return new NonContainer();
...
}
}

void foo()
{
auto o = getO(some information);
if (is(typeof(o) == Container) { ... }  // Doesn't work.
// Type is always A.
...
}

Is there a way to make getO return the most specialized type of 
the instantiated object in the switch statement to enable this 
pattern?


Re: Multiple return type from object factory possible?

2013-06-22 Thread Simen Kjaeraas

On Sat, 22 Jun 2013 18:58:22 +0200, deed n...@none.none wrote:


class A  { ... }
class NonContainer : A   { ... }
class Container : A  { A[] container; }
class NC1 : NonContainer {}
...
class C1 : Container {}
...

A getO(string info)
{
 switch (info)
 {
 default : return new NonContainer();
 case info1: return new C1();
 case info2: return new NC1();
 case info3: return new Container();
 case info4: return new NonContainer();
 ...
 }
}

void foo()
{
 auto o = getO(some information);
 if (is(typeof(o) == Container) { ... }  // Doesn't work.
 // Type is always A.
 ...
}

Is there a way to make getO return the most specialized type of the  
instantiated object in the switch statement to enable this pattern?


The type of an expression in D is determined at compile time, and getO
returns an A. Hence, o will always have static type A, and is(typeof(...
only checks the static type.

If you want to check the dynamic (run-time) type of o, you should
instead see if it is castable to Container:

auto o = getO(info3);
if (cast(Container)o != null) { ... }

--
Simen


Re: Multiple return type from object factory possible?

2013-06-22 Thread deed

auto o = getO(info3);
if (cast(Container)o != null) { ... }


Thanks Simen.
(Compiler requires !is instead of !=)