2015-01-22 8 views
6

Ich möchte eine Funktion in eine Dart-Oberklasse schreiben, die je nachdem, welche Unterklasse sie verwendet, unterschiedliche Aktionen ausführt. Etwas wie folgt aus:Klassenart in Dart einschalten

class Foo { 
    Foo getAnother(Foo foo) { 
    var fooType = //some code here to extract fooType from foo; 
    switch (fooType) { 
     case //something about bar here: 
     return new Bar(); 
     case //something about baz here: 
     return new Baz(); 
    } 
    } 
} 

class Bar extends Foo {} 

class Baz extends Foo {} 

, wo die Idee ist, dass ich einen Gegenstand haben, und wollen ein neues Objekt der gleichen (Unter-) Klasse erhalten.

Die Hauptfrage ist, welcher Typ sollte fooType sein? Mein erster Gedanke war Symbol, was zu einfachen Fallanweisungen wie case #Bar: führt, aber ich weiß nicht, wie ich fooType mit einem Symbol bevölkern würde. Die einzigen Optionen, die ich mir vorstellen kann, sind etwas wie Symbol fooType = new Symbol(foo.runtimeType.toString()); zu tun, aber mein Verständnis ist, dass runtimeType.toString() nicht funktioniert, wenn es in Javascript konvertiert wird. Sie könnten das umgehen, indem Sie Mirrors verwenden, aber das soll eine leichte Bibliothek sein, also sind diese nicht auf dem Tisch. Object.runtimeType gibt etwas von der Type Klasse zurück, aber ich habe keine Ahnung, wie Instanzen von Type ich für die Case-Anweisungen verwenden könnte. Vielleicht fehlt mir ein anderes Stück der Dart-Bibliothek, das dafür besser geeignet ist?

+0

Spezielles Verhalten für Unterklassen, abhängig von der Klasse: Das klingt genau so, was virtuelle Funktionen lösen sollen. Wie wäre es mit: 'Klasse Foo {Foo _createNew() => new Foo(); Foo getAnother (Foo foo) => foo._createNew(); } 'und dann' class Bar erweitert Foo {_createNew() => new Bar(); } 'und ähnlich für' Baz'? – lrn

Antwort

7

können Sie die runtimeType in switch benutzen ist

class Foo { 
    Foo getAnother(Foo foo) { 
    switch (foo.runtimeType) { 
     case Bar: 
     return new Bar(); 
     case Baz: 
     return new Baz(); 
    } 
    return null; 
    } 
} 

In den case Aussagen der Klassenname direkt verwenden (. Aka Klasse wörtliche). Dies ergibt ein Type Objekt, das der erwähnten Klasse entspricht. Somit kann foo.runtimeType mit dem angegebenen Typ verglichen werden.

Beachten Sie, dass you can not use generics for now in Klassenliterale. Daher ist case List<int>: nicht erlaubt.

+0

Erstaunlich! Ich hatte keine Ahnung, dass man solche Klassennamen verwenden könnte. Ich muss sagen, das scheint ein bisschen wie Magie zu sein. Kannst du mehr darüber erklären, wie diese Verwendung funktioniert (und vielleicht überhaupt über die Type-Klasse)? –

+0

Ich habe meine Antwort mit mehr Erklärungen aktualisiert. –

+0

Dies funktioniert nicht mit 'List' und' Map', 'Set' und wahrscheinlich anderen. –