Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在DART中创建泛型类型的实例_Dart - Fatal编程技术网

在DART中创建泛型类型的实例

在DART中创建泛型类型的实例,dart,Dart,我想知道是否可以在Dart中创建泛型类型的实例。在其他语言(如Java)中,您可以使用反射来解决这个问题,但我不确定在Dart中是否可以做到这一点 我有这门课: 类GenericController{ void processRequest(){ T=new T();//错误 } } 很抱歉,但据我所知,类型参数不能用于命名Dart中实例创建表达式中的构造函数 您可以使用类似的代码: 导入“省道:镜像”; void main(){ var控制器=新的GenericController(); co

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

我有这门课:

类GenericController{
void processRequest(){
T=new T();//错误
}
}

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

您可以使用类似的代码:

导入“省道:镜像”;
void main(){
var控制器=新的GenericController();
controller.processRequest();
}
类泛型控制器{
void processRequest(){
//T=新的T();
T=Activator.createInstance(T);
t、 告诉自己();
}
}
类Foo扩展了RequestHandler{
void tellAboutHimself(){
打印(“你好,我是‘福’”);
}
}
抽象类RequestHandler{
void telabouthimself();
}
类激活器{
静态createInstance(类型,[符号构造函数,列表
参数,映射名(参数]){
if(type==null){
抛出新ArgumentError(“type:$type”);
}
if(构造函数==null){
构造函数=常量符号(“”);
}
if(参数==null){
参数=const[];
}
var typeMirror=反射类型(类型);
if(typeMirror是ClassMirror){
返回typeMirror.newInstance(构造函数、参数、,
名称(组)。反映对象;
}否则{
抛出新ArgumentError(“无法创建“$type.”类型的实例”);
}
}
}

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

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

您可以这样定义一个方法类型:(必要时添加参数)

typedef S ItemCreator();
或者更好:

typedef ItemCreator=S函数();
然后在需要创建新实例的类中:

类页面列表数据{
...
物品创造者;
PagedListData(ItemCreator this.creator){
}
void performMagic(){
T item=creator();
... 
}
}
然后您可以像下面这样实例化
页面列表

PagedListData用户
=新的PagedListData(()=>新的UserListItem());

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

以下是我针对这一令人遗憾的限制所做的工作

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();
}
类请求处理程序{
静态最终构造函数={
RequestHandler:()=>RequestHandler(),
RequestHandler2:()=>RequestHandler2(),
};
静态RequestHandler创建(类型){
返回_构造函数[type]();
}
}
类RequestHandler2扩展了RequestHandler{}
类泛型控制器{
void processRequest(){
//T=new T();//错误
T=RequestHandler.create(T);
}
}
测试(){
最终控制器=通用控制器();
controller.processRequest();
}

我不知道这是否对任何人都有用。但我找到了一个简单的解决办法。在要初始化类型T的函数中,传递类型为
T function()
的额外参数。这个函数应该返回一个T的实例。现在,无论何时您想要创建T的对象,都可以调用这个函数

class foo<T> {
    void foo(T Function() creator) {
        final t = creator();
        // use t
    }
}

class-foo{
void foo(T函数()创建者){
最终t=创建者();
//使用t
}
}

p.S.灵感来源于处理颤振

typedef S ItemCreator<S>();

mixin SharedExtension<T> {

    T getSPData(ItemCreator<T> creator) async {
        return creator();
    }
}

Abc a = sharedObj.getSPData(()=> Abc());
typedef S ItemCreator();
混合蛋白{
T getSPData(ItemCreator-creator)异步{
返回创建者();
}
}
abca=sharedObj.getSPData(()=>Abc());

p.S.受

使用
Patricks
方法的启发,我试图解决
main.dart
中的代码复杂性。我正在我的应用程序中使用
MultiProvider
,使用
Patricks
方法后,我的代码如下所示

导入“包:app/presentation/home/shop/Cart.dart”;
导入“包:app/presentation/home/temple/TempleModel.dart”;
进口“包装:颤振/cupertino.dart”;
进口“包装:颤振/基础.dart”;
导入“包:provider/provider.dart”;
typedef ItemCreator=T函数();
ChangeNotifierProvider getTempleNotifiers(){
CreateNotifiers templeNotifier=新的CreateNotifiers(()=>new TempleModel());
返回templeNotifier.performMagic();
}
ChangeNotifierProvider getCartNotifiers(){
CreateNotifiers-cartNotifier=新的CreateNotifiers(()=>new CartModel());
返回cartNotifier.performMagic();
}
类CreateNotifiers{
物品创造者;
CreateNotifiers(ItemCreator this.creator);
ChangeNotifierProviderPerformMagic(){
T item=creator();
返回ChangeNotifierProvider(
创建:(构建上下文){
退货项目;
},
);
}
}

我有这两个模型
Cart
TempleModel
来处理我的应用程序数据。

Dart中的类型参数实现了接口
Type
类型
接口不声明任何成员。这意味着接口
Type
仅用作运行时类型的标识键。反射过程内置于Dart SDK中,但它们不是Dart核心的一部分。这意味着,如果您想内省您的程序,您应该使用反射库。程序(在运行时)和反射库之间的桥梁是接口
Type
。您可以请求(反映)有关使用此接口的类的必需信息。请参阅还不适用于颤振+下面是Patrik的方法。这是完美的。第二,关于颤振。节省了很多代码。它完全适合我。但是我不明白
creator()
是如何创建<
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;
      },
    );
  }
}