2013-01-09 26 views
8

Nel dardo è possibile creare un'istanza di una classe da una stringa?Istanziare una classe da una stringa

Ad esempio:

  • vaniglia in javascript:
var myObject = window[classNameString]; 
  • Objective-C:
id myclass = [[NSClassFromString(@"MyClass") alloc] init]; 

risposta

3

È necessario conoscere il nome della libreria e la classenome per far funzionare le cose correttamente. Supponiamo che tu conosca entrambi, l'esempio seguente instanzia il TestClass e chiama doStuff su di esso.

library test; 

import "dart:mirrors"; 

class TestClass { 
    doStuff() => print("doStuff was called!"); 
} 

main() { 
    MirrorSystem mirrors = currentMirrorSystem(); 
    LibraryMirror lm = mirrors.libraries['test']; 
    ClassMirror cm = lm.classes['TestClass']; 
    Future tcFuture = cm.newInstance('', []); 
    tcFuture.then((InstanceMirror im) { 
    var tc = im.reflectee; 
    tc.doStuff(); 
    }); 
} 

Alcune note su questa soluzione:

  1. La biblioteca test che stiamo cercando di caricare la classe da già importato nella VM, che rende questo caso, un po 'più facile.
  2. la chiamata newInstance consente di passare parametri al costruttore. Gli argomenti posizionali sono implementati, ma i parametri con nome non sono ancora implementati (come nella versione M2).
  3. newInstance restituisce un Future per consentirne il funzionamento su isolates.
+0

'newInstance' non restituisce un' Future' perché l'istanziazione della classe potrebbe richiedere un'operazione asincrona, non è vero, tutto è già caricato. Restituisce un 'Future' perché l'API Mirrors è intenzionalmente asincrona, in quanto funzionerà su tutti gli isolati in futuro (e la comunicazione cross-isolate è sempre asincrona). Se ispezionate attentamente l'invocazione 'newInstance' (e altri come' get/setField' o 'invoke' troppo), noterete che sotto il cofano funziona in modo sincrono. Ciò potrebbe ovviamente cambiare in futuro. – Ladicek

+0

Grazie Ladicek. Ho aggiornato la risposta. – Kyrra

+0

Nota: questo potrebbe non funzionare quando compilato in JavaScript. Il compilatore dart2js non supporta ancora pienamente i mirror. –

4

La sintassi è stata modificata. ho ottenuto che funziona in questo modo

library test; 

import "dart:mirrors"; 

class TestClass { 
    doStuff() => print("doStuff was called!"); 
} 

main() { 
    MirrorSystem mirrors = currentMirrorSystem(); 
    LibraryMirror lm = mirrors.libraries.values.firstWhere(
     (LibraryMirror lm) => lm.qualifiedName == new Symbol('test')); 

    ClassMirror cm = lm.declarations[new Symbol('TestClass')]; 

    InstanceMirror im = cm.newInstance(new Symbol(''), []); 
    var tc = im.reflectee; 
    tc.doStuff(); 
} 

Se ci sono più le librerie denominate 'test' questo non riuscirà però.

+0

Infatti, il getter 'classes' è stato cambiato in' declarationations'. – snitko

Problemi correlati