我是新来的颤栗和飞镖,来自本土Android。
Android有一个非常好的数据库抽象体系结构,称为Room Persistence Library。据我所知,使用MVVM / MVC设计模式并不存在这样的数据库抽象体系结构。
我的解决方案是自己创建一个Dart版本。在经历了几次头痛之后,我做了很多事情,但我似乎无法让LiveData使用泛型来正常工作。
我这样安排我的课:
class LiveData<T> {
...
}现在,当我想返回一些数据时,可以是Object或List<Object>。我发现了一个巧妙的方法来区分两者和T
...
// Parse response
// This checks if the type is an instance of a single entity or a list.
if (entity is T) {
cachedData = rawData.isEmpty ? null : entity.fromMap(rawData.first) as T;
} else {
cachedData = rawData.map((e) => entity.fromMap(e)).toList() as T;
}
...问题在于第二块:
cachedData = rawData.map((e) => entity.fromMap(e)).toList() as T;有错误:
- Unhandled Exception: type 'List<Entity>' is not a subtype of type 'List<Vehicle>' in type cast然后,问题就变成了:当我没有访问Entity类的权限时,如何将Vehicle转换为Vehicle。它的一个实例只分配给一个Entity entity变量。
下面是演示我访问Vehicle的一个片段
final Entity entity;
...assign Vehicle instance to entity...
print(entity is Vehicle) // True我试过使用.runtimeType,但没有效果。我还考虑过将LiveData分成两个类,第二个类是LiveDataList。虽然这似乎是最简单的解决方案,不错误的代码-它将困扰我(坏双关是故意的),并打破否则相当直接的端口的房间。
作为一种临时解决方案,我将构建逻辑抽象为一个泛型函数,以传递给构造函数中的LiveData。
final T Function(List<Map<String, dynamic>> rawData) builder;现在,我将其称为构建cachedData的前面的代码。
// Parse response
cachedData = builder(rawData);在访问LiveData<List<Vehicle>>中的所有车辆时调用Dao<Vehicle>的构造函数为:
class VehicleDao implements Dao<Vehicle> {
...
static LiveData<List<Vehicle>> get() {
return LiveData<List<Vehicle>>(
...
(rawData) => rawData.map((e) => Vehicle.fromMap(e)).toList(),
...
);
}
}发布于 2020-02-29 04:08:12
在Dart中(实际上在许多语言中),泛型都有继承的概念。您可能会认为,如果Bar是从Foo继承的,那么List<Bar>也可以传递给List<Foo>。
实际上,由于泛型的工作方式,情况不会如此。当您有一个泛型类时,每次使用该类具有不同类型时,该类型都被视为一个完全独立的类。这是因为当编译器编译这些类型时,class MyGenericType<Foo> extends BaseClass和class MyGenericType<Bar> extends BaseClass基本上被转换为class MyGenericType_Foo extends BaseClass和class MyGenericType_Bar extends BaseClass。
你看到问题了吗?MyGenericType_Foo和MyGenericType_Bar不是彼此的后代。他们是彼此的兄弟姐妹,都是从BaseClass延伸出来的。这就是为什么当您尝试将List<Entity>转换为List<Vehicle>时,转换不能工作,因为它们是同级类型,而不是超级类型和子类型。
尽管不能根据泛型类型参数的关系直接将一个泛型类型转换为另一个泛型类型,但在List的情况下,有一种方法可以将一种List类型转换为另一种类型:cast方法。
List<Entity> entityList = <Entity>[...];
List<Vehicle> vehicleList = entityList.cast<Vehicle>(); // This cast will work但是要注意的一点是,如果您要从超级泛型转换为子类型泛型,并且列表中的所有元素都是新类型,则此强制转换将引发一个错误。
https://stackoverflow.com/questions/60461815
复制相似问题