2013-12-23 1 views
2

если у меня есть экземпляр, и я знаю, что класс экземпляра содержит статический метод с именем statFn(), как я могу позвонить statFn() из экземпляра?в Dart, используя Mirrors, как бы вы назвали статический метод класса из экземпляра класса?

, например,

abstract class Junk { 
    ... 
} 
class Hamburger extends Junk { 
    static bool get lettuce => true; 
    ... 
} 
class HotDog extends Junk { 
    static bool get lettuce => false; 
    ... 
} 

Junk food; // either Hamburger or Hotdog 

// how do you get lettuce of food's type? 

ответ

3

Это должно вам начать. findStaticAndInvoke() рассматривает класс предоставленного объекта и его подклассы для статического метода или getter и вызывает его при обнаружении.

library x; 

import 'dart:mirrors'; 

abstract class Junk { 
    static void doSomething() { 
    print("Junk.doSomething()"); 
    } 
} 

class Hamburger extends Junk { 
    static bool get lettuce => true; 
} 

class HotDog extends Junk { 
    static bool get lettuce => false; 
} 

Junk food; // either Hamburger or Hotdog 

void main(List<String> args) { 
    Junk food = new HotDog(); 
    findStaticAndInvoke(food, "doSomething"); 
    findStaticAndInvoke(food, "lettuce"); 

    food = new Hamburger(); 
    findStaticAndInvoke(food, "doSomething"); 
    findStaticAndInvoke(food, "lettuce"); 
} 

void findStaticAndInvoke(o, String name) { 
    ClassMirror r = reflect(o).type; 
    MethodMirror sFn; 
    var s = new Symbol(name); 

    while (sFn == null && r != null) { 
    sFn = r.staticMembers[s]; 
    if(sFn != null) { 
     break; 
    } 
    r = r.superclass; 
    } 

    if(sFn != null) { 
    if(sFn.isGetter) { 
     print(r.getField(s).reflectee); 
    } 
    else { 
     r.invoke(s, []); 
    } 
    } 
} 
+0

какая клевая функция! Большое спасибо –

+0

Когда вы конвертируете такой код в javascript tree-shaking, могут отбросить некоторые функции, потому что он не может распознавать ссылки типа 'new Symbol ('someMethod'). Чтобы предотвратить это, вы можете использовать '@ MirrorsUsed' или' @ reflectable'. Если вы получаете ошибки, такие как 'xxx не имеет метода с именем yyy 'в JavaScript, это, вероятно, причина. –

+0

Вы бы использовали @reflectable в верхней части объявления класса? –

1

На стороне сервера (в чистом языке Dart, но не в JavaScript), вы можете попробовать использовать reflection библиотеку. Он написан как наложение поверх библиотеки dart:mirrors.

Он имеет такую ​​же функциональность и некоторые дополнительные полезные функции.

import 'package:reflection/reflection.dart'; 

abstract class Junk { 
    bool _fresh = true; 
    bool get fresh => _fresh; 
    void set fresh(fresh) { _fresh = fresh; } 
} 
class Hamburger extends Junk { 
    static bool get lettuce => true; 
} 
class HotDog extends Junk { 
    static bool get lettuce => false; 
} 

Junk food; 

void main() { 
    food = new Hamburger(); 
    var type = objectInfo(food).type; 
    var lettuce = type.getProperty(#lettuce, BindingFlags.PUBLIC | BindingFlags.STATIC); 
    print(lettuce.getValue()); 

    // Default: BindingFlags.PUBLIC | BindingFlags.INSTANCE 
    var fresh = type.getProperty(#fresh); 
    print(fresh.getValue(food)); 

    // Stale 
    fresh.setValue(food, false); 
    print(fresh.getValue(food)); 
} 
true 
true 
false 
+0

У вас есть ссылка на api для этого? –

+0

много удачи! Я узнал, что чем больше вы достигнете, тем больше ожиданий, поэтому убедитесь, что вы сохраняете свое здравомыслие :) –