我想知道是否可以在Dart中创建泛型类型的实例。在像Java这样的其他语言中你可以使用反射来解决这个问题,但是我不确定这是否可以在Dart中使用。
我有这堂课:
class GenericController <T extends RequestHandler> {
void processRequest() {
T t = new T(); // ERROR
}
}
答案 0 :(得分:31)
我尝试了使用Activator的mezonis方法并且它有效。但这是一种昂贵的方法,因为它使用镜像,如果你不想拥有2-4MB的js文件,则需要你使用“mirrorsUsed”。
今天早上我有了使用泛型typedef作为生成器的想法,从而摆脱了反射:
您可以定义如下方法类型:(必要时添加参数)
typedef S ItemCreator<S>();
然后在需要创建新实例的类中:
class PagedListData<T>{
...
ItemCreator<T> creator;
PagedListData(ItemCreator<T> this.creator) {
}
void performMagic() {
T item = creator();
...
}
}
然后你可以像这样实现PagedList:
PagedListData<UserListItem> users
= new PagedListData<UserListItem>(()=> new UserListItem());
您没有失去使用泛型的优势,因为在声明时您无论如何都需要提供目标类,因此定义创建者方法不会受到伤害。
答案 1 :(得分:4)
我不知道这是否仍然对任何人有用。但是我发现了一个简单的解决方法。在要初始化类型T的函数中,传递类型T Function()
的额外参数。此函数应返回T的实例。现在,无论何时要创建T的对象,都请调用该函数。
class foo<T> {
void foo(T Function() creator) {
final t = creator();
// use t
}
}
P.S。受Patrick's answer
的启发答案 2 :(得分:3)
您可以使用类似的代码:
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'.");
}
}
}
答案 3 :(得分:1)
很抱歉,但据我所知,类型参数不能用于在Dart中的实例创建表达式中命名构造函数。
答案 4 :(得分:0)
这是我为这个可悲的限制所做的工作
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();
}
答案 5 :(得分:0)
使用FLutter
typedef S ItemCreator<S>();
mixin SharedExtension<T> {
T getSPData(ItemCreator<T> creator) async {
return creator();
}
}
Abc a = sharedObj.getSPData(()=> Abc());
P.S。受Patrick
的启发答案 6 :(得分:0)
使用 Patricks
方法,我尝试解决 main.dart
中的代码复杂性。我在我的应用程序中使用 MultiProvider
,在使用 Patricks
方法后,我的代码如下所示,
import 'package:app/presentation/home/shop/Cart.dart';
import 'package:app/presentation/home/temple/TempleModel.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:provider/provider.dart';
typedef ItemCreator<T> = T Function();
ChangeNotifierProvider getTempleNotifiers(){
CreateNotifiers<TempleModel> templeNotifier = new CreateNotifiers<TempleModel>(()=> new TempleModel());
return templeNotifier.performMagic();
}
ChangeNotifierProvider getCartNotifiers(){
CreateNotifiers<CartModel> cartNotifier = new CreateNotifiers<CartModel>(()=> new CartModel());
return cartNotifier.performMagic();
}
class CreateNotifiers<T extends ChangeNotifier> {
ItemCreator<T> creator;
CreateNotifiers(ItemCreator<T> this.creator);
ChangeNotifierProvider performMagic() {
T item = creator();
return ChangeNotifierProvider<T>(
create: (BuildContext context) {
return item;
},
);
}
}
我有这两个模型 Cart
和 TempleModel
来处理我的应用数据。