7

I'm trying to pass a Class reference and instantiate it in a function. This doesn't work:

function foo(myClassRef:Class):Void {
    var myVar = new myClassRef();
}
foo(MyClass);

It gives Unexpected (.

Is this possible in Haxe 3?

Gama11
  • 31,714
  • 9
  • 78
  • 100
Jorjon
  • 5,316
  • 1
  • 41
  • 58

2 Answers2

13

Class has a Type Parameter, so if you're going to accept a class as an argument, you need to specify a type parameter.

Accept any class:

function foo(myClassRef:Class<Dynamic>):Void {
    var myVar = Type.createInstance( myClassRef, [constructorArg1, constructorArg2....] );
    trace( Type.typeof(myVar) );
}

Accept only "sys.db.Object" class or sub classes:

function foo(myClassRef:Class<sys.db.Object>):Void {
    var myVar = Type.createInstance( myClassRef, [] );
    trace( Type.typeof(myVar) );
}

Haxe 3 also allows generic functions:

@:generic function foo<T:Dynamic>(t:Class<T>) {
    var myVar = new T();
    trace( Type.typeof(myVar) );
}

Here you declare the function to be generic, which means that for each different type parameter, a different version of the function will be compiled. You accept Class, where T is the type parameter - in this case, dynamic, so it will work with any class. Finally, using generic functions let's you write new T(), which may seem a more natural syntax, and there may be performance benefits on some platforms.

Jason O'Neil
  • 5,908
  • 2
  • 27
  • 26
  • I just want to add, that with Dead Code Elimination set to full (-dce full), the constructor of the class would be eliminated if it's not used anywhere else. To fix this, we should prepend the constructor signature with @:keep metadata, [like this](https://github.com/HaxeFoundation/haxe/issues/1891). – Jorjon Oct 29 '14 at 16:08
  • I may be wrong, but according to the documentation (haxe 3.2.0) it's `Type.createInstance( myClassRef, [args]);` That is, no `constructor` in the params. – chichilatte Nov 06 '15 at 18:33
  • That was just me writing trying to write a sentence. I could have also written `Type.createInstance(myClassRef, [arg1,arg2,arg3])`. Sorry for the confusion, I'll edit the answer – Jason O'Neil Nov 10 '15 at 03:47
4

It is possible in Haxe3 and Haxe2

function foo<T>(myClassRef:T):Void {
var myVar = new T();

}

Note: Haxe3 class (where foo is implemented) must be @:generic if you want new T() to work.

Haxe2 is another story:

function foo<T>(myClassRef:Class<T>):Void {
var myVar = Type.createEmptyInstance(Type.getClass(myClassRef));

}

Vox
  • 59
  • 2