Saltar al contenido

Creación de una instancia de un tipo genérico en DART

Solución:

Probé el enfoque de mezonis con el Activador y funciona. Pero es un enfoque costoso ya que usa espejos, lo que requiere que use “mirrorsUsed” si no desea tener un archivo js de 2-4 MB.

Esta mañana tuve la idea de usar un typedef genérico como generador y así deshacerme de la reflexión:

Usted define un tipo de método como este: (Agregue parámetros si es necesario)

typedef S ItemCreator<S>();

Luego, en la clase que necesita crear las nuevas instancias:

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

  }

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

Entonces puedes instanciar el PagedList como esto:

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

No pierde la ventaja de usar genérico porque en el momento de la declaración debe proporcionar la clase de destino de todos modos, por lo que definir el método del creador no está de más.

Puede utilizar un código similar:

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'.");
    }
  }
}

Aquí está mi trabajo para esta triste limitación

class RequestHandler {
  static final _constructors = {
    RequestHandler: () => RequestHandler(),
    RequestHandler2: () => RequestHandler2(),
  };
  static RequestHandler create(Type type) {
    return _constructors[type]();
  }
}

class RequestHandler2 extends RequestHandler {}

class GenericController<T extends RequestHandler> {
  void processRequest() {
    //T t = new T(); // ERROR
    T t = RequestHandler.create(T);
  }
}

test() {
  final controller = GenericController<RequestHandler2>();
  controller.processRequest();
}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags :

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *