2014-04-16 8 views
5

Zastanawiam się, czy możliwe jest utworzenie instancji typu ogólnego w Dart. W innych językach, takich jak Java, można obejść to za pomocą refleksji, ale nie jestem pewien, czy jest to możliwe w Dart.Tworzenie instancji typu ogólnego w DART

mam tej klasy:

class GenericController <T extends RequestHandler> { 

    void processRequest() { 
     T t = new T(); // ERROR 
    } 
} 
+0

Parametry typu w Dart implementuje interfejs "Typ". Interfejs 'Type' nie deklaruje żadnych członków. Oznacza to, że interfejs "Typ" używany jest tylko jako klucz tożsamości typów uruchomieniowych. Procedury odbicia wbudowane w Dart SDK, ale nie są częścią rdzenia Dart. Oznacza to, że jeśli chcesz zgłębić swój program, powinieneś użyć biblioteki refleksów. Pomost pomiędzy twoim programem (przy uruchomieniu) a biblioteką refleksów to interfejs 'Typ'. Żądasz (odzwierciedla) wymagane informacje o klasach za pomocą tego interfejsu. – mezoni

+0

Zobacz także https://github.com/dart-lang/sdk/issues/12921 –

Odpowiedz

4

Można użyć podobny kod:

import "dart:mirrors"; 

void main() { 
    var controller = new GenericController<Foo>(); 
    controller.processRequest(); 
} 

class GenericController<T extends RequestHandler> { 
    void processRequest() { 
    //T t = new T(); 
    T t = Activator.createInstance(T); 
    t.tellAboutHimself(); 
    } 
} 

class Foo extends RequestHandler { 
    void tellAboutHimself() { 
    print("Hello, I am 'Foo'"); 
    } 
} 

abstract class RequestHandler { 
    void tellAboutHimself(); 
} 

class Activator { 
    static createInstance(Type type, [Symbol constructor, List 
     arguments, Map<Symbol, dynamic> namedArguments]) { 
    if (type == null) { 
     throw new ArgumentError("type: $type"); 
    } 

    if (constructor == null) { 
     constructor = const Symbol(""); 
    } 

    if (arguments == null) { 
     arguments = const []; 
    } 

    var typeMirror = reflectType(type); 
    if (typeMirror is ClassMirror) { 
     return typeMirror.newInstance(constructor, arguments, 
     namedArguments).reflectee; 
    } else { 
     throw new ArgumentError("Cannot create the instance of the type '$type'."); 
    } 
    } 
} 
+0

Dzięki mezoni, że działa zgodnie z oczekiwaniami – shuriquen

0

przepraszam, ale o ile mi wiadomo, to parametr typu nie może być używany, aby wymienić konstruktora w wyrażeniu utworzenia instancji w Dart.

4

Próbowałem mezonis podejście z aktywatorem i to działa. Jest to jednak kosztowne podejście, ponieważ korzysta z serwerów lustrzanych, co wymaga użycia "mirrorsUsed", jeśli nie chcesz mieć pliku JS o wielkości 2-4 MB.

Dziś rano miałem pomysł, aby użyć rodzajowego typedef jako generatora i tym samym pozbyć się refleksji:

zdefiniować rodzaj metody takie jak to: (Dodaj params jeśli to konieczne)

typedef S ItemCreator<S>(); 

Następnie w klasie, które muszą tworzyć nowe instancje:

class PagedListData<T>{ 
    ... 
    ItemCreator<T> creator; 
    PagedListData(ItemCreator<T> this.creator) { 

    } 

    void performMagic() { 
     T item = creator(); 
     ... 
    } 
} 

Następnie można instanciate się PagedList tak:

PagedListData<UserListItem> users 
     = new PagedListData<UserListItem>(()=> new UserListItem()); 

Nie stracić Zaletą korzystania generic ponieważ w momencie zgłoszenia należy podać klasę docelową tak, więc określanie sposobu twórca nie boli.