2016-07-07 5 views
2

Предположим, что все 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 существуют?

+0

Я просто хочу сказать, что это - в общем - не очень хороший образец. Если вы не пытаетесь сделать это (или это не просто языковой эксперимент), попробуйте выбрать другой подход без 'dart: mirror'. – filiph

+0

Почему у вас 3 'typedef' не работает в вашем сценарии? Вы можете передать 3 (функциональные) ссылки и составить способ, который вам нужен. –

ответ

2

Для этого с использованием dart:mirrors:

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

Теперь, если вы заключаете, что в вспомогательный метод «call», то callGenerically может выглядеть следующим образом:

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

Вы можете увидеть полный пример this DartPad.

Обратите внимание, что

  • Это является анти-модель, и это лучше общаться с системой типа Дарта какие методы, как ожидается, существуют. Если вы знаете, что классы имеют один и тот же API, просто используйте обычный полиморфизм вместо отражения, как в ответе Джонаса.
  • Использование dart:mirrors исключает дрожание деревьев в dart2js, что приводит к раздуванию JS.
  • Звонок f3 нуждается в аргументе, следовательно, второй arg в callGenerically.
1

Я полагаю, что для этого без работы dart:mirrors, metaclasses необходимо будет приземлиться.

Код в in Dart, using Mirrors, how would you call a class's static method from an instance of the class? поможет вам начать - не уверен, что он все еще работает так же, это довольно много времени, я отправил ответ: D

+0

Это полезно - но я не хочу создавать экземпляр, который в противном случае не нужен, просто получите зеркала для вызова статической функции. Кроме того, нет гарантии, что T имеет значение по умолчанию ctor. Я не видел обсуждения в метаклассе, и это выглядит так, как я буду. – user1338952

+0

Я долгое время не использовал 'dart: mirror' и не помню деталей. –

+1

В 'dart: mirror' вам понадобится' reflectType (T1).invoke (# f1, []) 'как в http://dartpad.dartlang.org/cd1bb844eaa48b210e53cd0b7b31a1e0 – Ganymede

2

Эта конструкция выбирает статические функции. Возможно, есть и другие.

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

Т1 Fsum (1): 4

Т1 callGenerically (1): 4

Т2 Fsum (1): 7

Т2 callGenerically (1): 7