如何将类型传递给函数并调用其静态方法?

时间:2016-07-07 15:52:15

标签: dart

假设T1,T2和T3都有静态函数f1,f2,f3,我想一般打电话。

如何轻松实现这样的目标?

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);
}

这会打印T1,因此它正在获取类型。只是不知道如何调用它上面的静态函数。即使预期f1,f2,f3存在,镜像也是一个选项或要求吗?

3 个答案:

答案 0 :(得分:2)

使用reflectType(SomeClass).invoke(#someStaticMethod, []).reflectee; 执行此操作:

call

现在,如果您将其包装在辅助方法" callGenerically"中,那么callGenerically(Type type, num arg) => call(type, #f1, [call(type, #f2, [call(type, #f3, [arg])])]); 可能如下所示:

dart:mirrors

您可以在this DartPad中看到完整示例。

请注意

  • 这是一种反模式,与Dart的类型系统进行通信时,预计会有哪些方法存在。如果你知道这些类具有相同的API,那么只需使用普通的多态而不是反射,就像Jonas'答案。
  • 使用f3排除dart2js中的树抖动,产生臃肿的JS。
  • callGenerically的调用需要一个参数,因此function changer(obj) { obj.foo = 'bar'; } var num = new Number(123); console.log(num.foo); // undefined changer(num); console.log(num.foo); // 'bar'中的第二个参数。

答案 1 :(得分:1)

我想这可以在没有dart:mirrors的情况下工作,here需要登陆。

metaclasses中的代码应该让你开始 - 不确定它是否仍然有效,我已经发布答案了很长一段时间:D

答案 2 :(得分:1)

此构造选择静态函数。也许还有其他人。

typedef int fadd_t(final int i);

abstract class T {
  final fadd_t f1;
  final fadd_t f2;
  final fadd_t f3;

  T(final this.f1, final this.f2, final this.f3);

  int fsum(final int i){
     return f1(f2(f3(i)));
  }
}

class T1 extends T {

  T1() : super(lf1, lf2, lf3){
  }

  static lf1(i) => i+1;
  static lf2(i) => i+1;
  static lf3(i) => i+1;
}

class T2 extends T {

  T2() : super(lf1, lf2, lf3){
  }

  static lf1(i) => i+2;
  static lf2(i) => i+2;
  static lf3(i) => i+2;
}

callGenerically(final T t, final int i) {
  return t.f1(t.f2(t.f3(i)));
}


main() {

    T1 t1 = new T1();
    print('T1 fsum(1) : ' + t1.fsum(1).toString() );
    print('T1 callGenerically(1) : ' + callGenerically(t1, 1).toString() );

    T2 t2 = new T2();
    print('T2 fsum(1) : ' + t2.fsum(1).toString() );
    print('T2 callGenerically(1) : ' + callGenerically(t2, 1).toString() );
}

T1 fsum(1):4

T1 callGenerically(1):4

T2 fsum(1):7

T2 callGenerically(1):7