Thread overview
Multiple return type from object factory possible?
Jun 22, 2013
deed
Jun 22, 2013
Simen Kjaeraas
Jun 22, 2013
deed
June 22, 2013
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?
June 22, 2013
On Sat, 22 Jun 2013 18:58:22 +0200, deed <none@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
June 22, 2013
>     auto o = getO("info3");
>     if (cast(Container)o != null) { ... }

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