user1338952 user1338952 - 4 months ago 8
Dart Question

How to pass a type to a function and invoke its static methods?

Suppose T1, T2 and T3 all have static functions f1, f2, f3 that I'd like to call generically.

How can something like this easily be achieved?

class T1 {
static f1(i) => i+1;
static f2(i) => i+1;
static f3(i) => i+1;
}

class T2 {
static f1(i) => i+2;
static f2(i) => i+2;
static f3(i) => i+2;
}

class T3 {
static f1(i) => i+3;
static f2(i) => i+3;
static f3(i) => i+3;
}

callGenerically(dynamic type) {
print(type);

type.f1(type.f2(type.f3));
}

main() {
callGenerically(T1);
callGenerically(T2);
callGenerically(T3);
}


This prints T1, so it is getting the type. Just don't know how to invoke the static functions on it. Is mirrors an option or requirement even though it is expected f1,f2,f3 exist?

Answer

To do this using dart:mirrors:

reflectType(SomeClass).invoke(#someStaticMethod, []).reflectee;

Now if you wrap that in a helper method "call", then callGenerically can look like:

callGenerically(Type type, num arg) =>
    call(type, #f1, [call(type, #f2, [call(type, #f3, [arg])])]);

You can see a full example in this DartPad.

Note that

  • This is an anti-pattern and it's better to communicate to Dart's type system what methods are expected to exist. If you know the classes have the same API, just use ordinary polymorphism instead of reflection, like in Jonas' answer.
  • Using dart:mirrors precludes tree-shaking in dart2js, producing bloated JS.
  • The call to f3 needs an argument, hence the second arg in callGenerically.
Comments