www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Multiple return type from object factory possible?

reply "deed" <none none.none> writes:
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?
Jun 22 2013
parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
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
Jun 22 2013
parent "deed" <none none.none> writes:
     auto o = getO("info3");
     if (cast(Container)o != null) { ... }
Thanks Simen. (Compiler requires !is instead of !=)
Jun 22 2013