Search code examples
constructorhaxegeneric-type-argument

Construction of generic type parameter in Haxe


I'm trying to instantiate a class based on a function type parameter.
Although the documentation says it is possible, I can't make it work.

Consider the following code:

// Dialog base class
// Every dialog in my application will derive from this
class Dialog
{
    public function new()
    {
        // do some stuff here
    }
}

// One of the possible dialogs in the application
// Extends Dialog
class TestDialog extends Dialog
{
    public function new()
    {
        super();
        // do some more stuff
    }
}

// A simple class that tries to instantiate a specialized dialog, like TestDialog 
class SomeAppClass
{
    public function new() 
    {
        var instance = create(TestDialog);
    }

    @:generic
    function create<T:Dialog>(type:Class<T>):T
    {
        return new T();
    }
}

This doesn't work with the following error:
create.T does not have a constructor

Clearly, I'm doing something wrong, but what?


Solution

  • SpecialDialog could have a different constructor than Dialog. So you have to constraint it and then also constraint to Dialog.

    Code @ Try Haxe

    package;
    
    
    typedef Constructible = {
      public function new():Void;
    }
    
    
    // Dialog base class
    // Every dialog in my application will derive from this
    class Dialog
    {
        public function new()
        {
            trace("dialog");
        }
    }
    
    
    class SuperDialog extends Dialog
    {
        public function new()
        {
            super();
            trace("super dialog");
        }
    }
    
    // A simple class that tries to instantiate a specialized dialog, like TestDialog 
    
    class SomeAppClass
    {
        public function new() 
        {
            var dialog = create(Dialog);
            var superDialog = create(SuperDialog);
        }
    
        @:generic
        public static function create<T:(Constructible,Dialog)>(type:Class<T>):T
        {
            return new T();
        }
    }
    
    class Test {
      static public function main() {
        new SomeAppClass();
      }
    }