在DART中创建通用类型的实例

Creating an instance of a generic type in DART

我想知道是否有可能在Dart中创建泛型类型的实例。 在其他语言(如Java)中,您可以使用反射来解决此问题,但是我不确定在Dart中是否可行。

我有这个课:

1
2
3
4
5
6
class GenericController <T extends RequestHandler> {

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


我尝试了使用Activator的mezonis方法,并且有效。 但这是一种昂贵的方法,因为它使用镜像,如果您不想拥有2-4MB的js文件,则需要使用" mirrorsUsed"。

今天早上,我想到了使用通用的typedef作为生成器,从而摆脱了反射:

您可以定义这样的方法类型:(如有必要,请添加参数)

1
typedef S ItemCreator();

然后在需要创建新实例的类中:

1
2
3
4
5
6
7
8
9
10
11
12
class PagedListData< T >{
  ...
  ItemCreator< T > creator;
  PagedListData(ItemCreator< T > this.creator) {

  }

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

然后,您可以像这样实例化PagedList:

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

您不会失去使用泛型的优势,因为在声明时无论如何都需要提供目标类,因此定义creator方法不会受到损害。


您可以使用类似的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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'.");
    }
  }
}


抱歉,据我所知,不能在Dart中的实例创建表达式中使用类型参数来命名构造函数。


这是我为这个可悲的局限性所做的工作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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();
}