You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter BLoC场景下如何判断转发的事件实例是否属于抽象类

问题分析与解决方案

问题根源

你传入的itemSelectedEvent是一个闭包函数,它的作用是接收两个int参数后返回EditItemDeselected实例,但闭包本身并不是EditEvent类型的对象。调试器显示的{_Closure} Closure: (int, int) => EditItemDeselected也明确说明了这一点——你判断的是函数对象的类型,而非它返回值的类型,所以is判断始终返回false。

可行解决方案

方案1:使用泛型约束(推荐)

将ChildWidget改为泛型Widget,通过泛型参数标记事件类型,同时约束泛型为你的事件抽象类:

class ChildWidget<T extends Equatable> extends StatelessWidget {
  final T Function(int, int) itemSelectedEvent;

  const ChildWidget({super.key, required this.itemSelectedEvent});

  @override
  Widget build(BuildContext context) {
    // 根据泛型类型判断场景
    if (T == EditEvent) {
      // 处理普通编辑场景的逻辑
    } else if (T == EditMasterEvent) {
      // 处理主编辑场景的逻辑
    }

    // 生成事件时直接调用函数:
    // final event = itemSelectedEvent(1, 2);
    // context.read<YourBloc>().add(event);

    return // ...你的Widget结构
  }
}

调用时Dart会自动推断泛型类型,也可以显式指定:

// 自动推断类型
ChildWidget(itemSelectedEvent: (i, j) => EditItemDeselected(i, j))
// 显式指定类型
ChildWidget<EditEvent>(itemSelectedEvent: (i, j) => EditItemDeselected(i, j))

方案2:封装事件工厂对象

定义一个类同时封装事件生成函数和类型标记,让类型判断更直观:

class EventCreator<T extends Equatable> {
  final T Function(int, int) create;
  final Type eventType;

  const EventCreator(this.create, this.eventType);
}

修改ChildWidget的参数:

class ChildWidget extends StatelessWidget {
  final EventCreator itemSelectedCreator;

  const ChildWidget({super.key, required this.itemSelectedCreator});

  @override
  Widget build(BuildContext context) {
    if (itemSelectedCreator.eventType == EditEvent) {
      // 普通场景逻辑
    } else if (itemSelectedCreator.eventType == EditMasterEvent) {
      // 主场景逻辑
    }

    // 生成事件
    final event = itemSelectedCreator.create(1, 2);
    return // ...你的Widget结构
  }
}

调用时传入封装好的对象:

ChildWidget(
  itemSelectedCreator: EventCreator(
    (i, j) => EditItemDeselected(i, j),
    EditEvent,
  ),
)

方案3:传入类型标记参数

如果不想修改太多结构,可以给ChildWidget加一个类型参数直接标记场景:

class ChildWidget extends StatelessWidget {
  final Function(int, int) itemSelectedEvent;
  final Type eventType;

  const ChildWidget({super.key, required this.itemSelectedEvent, required this.eventType});

  @override
  Widget build(BuildContext context) {
    if (eventType == EditEvent) {
      // 普通场景逻辑
    } else if (eventType == EditMasterEvent) {
      // 主场景逻辑
    }
    return // ...你的Widget结构
  }
}

调用时传入对应的类型:

ChildWidget(
  itemSelectedEvent: (i, j) => EditItemDeselected(i, j),
  eventType: EditEvent,
)

内容的提问来源于stack exchange,提问作者w461

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 21:36:05