Dart 泛型编程

Posted

技术标签:

【中文标题】Dart 泛型编程【英文标题】:Dart generic programming 【发布时间】:2021-12-18 20:20:58 【问题描述】:

我正在尝试为 Flutter 项目实现一个 BLOC 模式,我的代码可重复使用,因此我决定使用泛型编程来实现它。

首先我定义了事件类:

import 'package:flutter_bloc/flutter_bloc.dart';

abstract class AbstractSelectionEvent<T> 
  final T obj;

  AbstractSelectionEvent(this.obj);


class SelectedEvent<T> extends AbstractSelectionEvent<T> 
  SelectedEvent(T obj) : super(obj);


class UnselectedEvent<T> extends AbstractSelectionEvent<T> 
  UnselectedEvent(T obj) : super(obj);


class ChangeSelectionEvent<T> extends AbstractSelectionEvent<T> 
  ChangeSelectionEvent(T obj) : super(obj);

然后是状态类:

abstract class AbstractSelectionState<T> 
  final Set<T> selected;

  AbstractSelectionState(this.selected);

  AbstractSelectionState<T> select(T obj);

  AbstractSelectionState<T> unselect(T obj);

  AbstractSelectionState<T> changeSelect(T obj);

  AbstractSelectionState<T> reset(T obj);


class SelectedState<T> extends AbstractSelectionState<T> 
  SelectedState(Set<T> selected) : super(selected);

  SelectedState<T> select(T obj) => SelectedState<T>(selected..add(obj));

  SelectedState<T> unselect(T obj) => SelectedState<T>(selected..remove(obj));

  SelectedState<T> changeSelect(T obj) =>
      selected.contains(obj) ? unselect(obj) : select(obj);

  SelectedState<T> reset(T obj) => SelectedState<T>(<T>);


最后,当我编写 BLOC 类时,我遇到了一些麻烦。


abstract class SelectionBloc<
    T,
    E extends AbstractSelectionEvent<T>,
    S extends AbstractSelectionState<T>
  > extends Bloc<E, S> 
  SelectionBloc(S initialState) : super(initialState) 
    
    // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ The first error
    on<SelectedEvent<T>>((event, emit) 
      
      //   ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ The second error
      emit(state.select(event.obj));
      
    );
    
  

第一个错误说

'SelectedEvent<T>' doesn't conform to the bound 'E' of the type parameter 'E'.


Try using a type that is or is a subclass of 'E'.

第二个错误:

The argument type 'AbstractSelectionState<T>' can't be assigned to the parameter type 'S'.

对于第二个错误,我知道selectunselectchangeSelectreset 函数返回AbstractSelectionState&lt;T&gt;

SelectionBloc 期望emit 函数的S 状态,它是AbstractSelectionState&lt;T&gt; 的子类。

但另一方面,AbstractSelectionState&lt;T&gt; 类是抽象的,这意味着函数的返回值必须是AbstractSelectionState&lt;T&gt; 子类的实例。

这个问题可以解决吗?

【问题讨论】:

【参考方案1】:

这应该可行:

abstract class SelectionBloc<T>
    extends Bloc<AbstractSelectionEvent<T>, AbstractSelectionState<T>> 

  SelectionBloc(AbstractSelectionState<T> initialState) : super(initialState) 
    
    on<AbstractSelectionEvent<T>>((
      event,
      emit,
    ) 
      emit(state.select(event.obj));
    );
    
  

【讨论】:

以上是关于Dart 泛型编程的主要内容,如果未能解决你的问题,请参考以下文章

泛型编程类型约束与软件扩展性--面向可扩展的泛型编程就是面相类型约束编程

泛型编程的术语

尝鲜 Dart 2.7 最新语法之泛型强化:声明处型变

尝鲜 Dart 2.7 最新语法之泛型强化:声明处型变

C#泛型编程

Java编程手册-泛型