简体   繁体   English

你能用抽象类来构造泛型吗?

[英]Can you use an abstract class to construct a generic?

Im trying to use a constructor on a generic but since a generic ( represented here with T ) can be anything I'm trying to make T be of type "RedClass".我试图在泛型上使用构造函数,但由于泛型(这里用 T 表示)可以是任何我试图让 T 成为“RedClass”类型的东西。 If I then pass a class to represent T that also extends "RedClass" I would be able to use a RedClass constructor on T, right?如果我然后传递一个类来表示也扩展了“RedClass”的 T,我将能够在 T 上使用 RedClass 构造函数,对吗?

abstract class RedClass {
  RedClass();

  RedClass.fromJson(Map<String, dynamic> json)
}

class BlueClass extends RedClass {
  BlueClass();
}

class FinalClass<T extends RedClass> {

// Inside FinalClass I can create a BlueClass from the generic T

final happyBlueClass = T.fromJson(someJson)

}

// When creating the FinalClass i pass a class that also extends RedClass
return FinalClass<BlueClass>()

But trying this the generic T does not seem to get access to any .fromJson() constructor.但是尝试这个通用 T 似乎无法访问任何 .fromJson() 构造函数。 Any ideas?有任何想法吗?

Thank you all for the suggestions.谢谢大家的建议。 I really appreciate it.对此,我真的非常感激。

My solution for now to make the T of FinalClass as generic as possible I needed to pass the constuctors to FinalClass using a provider earlier in the widget tree.我现在的解决方案是使 FinalClass 的 T 尽可能通用,我需要使用小部件树中较早的提供程序将构造函数传递给 FinalClass。

class FinalClassDataBuilder {
 final Type model;
 final Function builder;

 FinalClassDataBuilder({this.model, this.builder});
}

class FinalClassProvider extends StatelessWidget {
 final Widget child;
 final List<FinalClassDataBuilder> modelbuilderList;

 const FinalClassProvider({Key key, this.child, this.modelbuilderList})
  : super(key: key);

 @override
 Widget build(BuildContext context) {
  return Provider<List<FinalClassDataBuilder>>(
   create: (_) => [...modelbuilderList],
   child: child,
  );
 }
}

class FinalClass<T> {
 ...
 final List<FinalClassDataBuilder> builders =
    Provider.of<List<FinalClassDataBuilder>>(context);

final List<<FinalClassDataBuilder>> result = builders
    .where((datamodel) => datamodel.model.toString() == T.toString())
    .toList();
}

There is no way to do what you are trying to do directly.没有办法直接做你想做的事情。

You cannot call static methods on type variables, only on the class/mixin/extension they are actually declared in. Static methods need to be known statically , at compile-time, in order to be called.你不能在类型变量上调用静态方法,只能在它们实际声明的类/混合/扩展上调用。静态方法需要在编译时静态地知道,以便被调用。

If you want to create an instance of the type variable, you need to pass a way to do so to the class.如果要创建类型变量的实例,则需要向类传递这样做的方法。 Maybe:也许:

class FinalClass<T extends RedClass> {
  final T Function(dynamic) _fromJson;

  FinalClass(T Function(dynamic) fromJson) : _fromJson = fromJson;
  void someMethod(someJson) {
    ... 
    var happyBlueClass = _fromJson(someJson);
    ...
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM