代码之家  ›  专栏  ›  技术社区  ›  w461

检查通过引用转发的类实例是否是抽象类的成员

  •  1
  • w461  · 技术社区  · 1 年前

    使用BLoC作为状态管理,我想检查转发到另一个小部件的事件是否属于某个BLoC抽象类。原因是我使用了一个包含小部件的表单,用于两种不同的用例/BLoC,并且根据BLoC的不同,我需要使用不同的事件。用例之间还有一个小的其他区别,这就是为什么我想通过调用小部件时传递的事件来识别用例。当然,我也可以传递一个带有该信息的bool,但后来想为什么不识别事件的抽象类。

    假设我有

    abstract class EditEvent extends Equatable {
      const EditEvent();
    }
    
    class EditItemDeselected extends EditEvent {
      EditItemDeselected(this.outerIdx, this.innerIdx);
      final int outerIdx, innerIdx;
      @override
      List<Object?> get props => [outerIdx, innerIdx];
    }
    
    abstract class EditMasterEvent extends Equatable {
      const EditMasterEvent();
    }
    
    class EditMasterItemDeselected extends EditMasterEvent {
      EditMasterItemDeselected(this.outerIdx, this.innerIdx);
      final int outerIdx, innerIdx;
      @override
      List<Object?> get props => [outerIdx, innerIdx];
    }
    

    然后,在一些小部件中,我用调用子小部件

    ChildWidget(itemSelectedEvent: (int i, int j) => EditItemDeselected(i, j))

    中的参数 ChildWidget 声明为 final Function(int, int) itemSelectedEvent;

    现在,在里面 ChildWidget 类似的东西 if (itemSelectedEvent is EditEvent) 不起作用,也不起作用 if (itemSelectedEvent is EditItemDeselected) 。它总是导致 false .

    调试器显示为 itemSelectedEvent {_Closure} Closure: (int, int) => EditItemDeselected

    1 回复  |  直到 1 年前
        1
  •  1
  •   Jannik    1 年前

    自从你宣布 itemSelectedEvent dynamic Function(int, int) itemSelectedEvent is EditEvent 将始终返回false,因为 itemSelectedEvent Function 而不是 EditEvent .

    您需要调用函数来获取返回类型。如果你设置 itemSelectedEvent (int i, int j) => EditItemDeselected(i, j) itemSelectedEvent(1, 2) is EditEvent 将返回true。

    注意:在OOP中,类型检查被认为是一种糟糕的做法。因为切换用例需要在代码中重复,如果添加新类型,则需要调整所有类型。

    class ChildWidget {
      ChildWidget(this.itemSelectedEvent);
    
      final Function(int, int) itemSelectedEvent;
    
      void func(int i1, int i2) {
        if (itemSelectedEvent(i1, i2) is EditEvent) {
          // do if EditEvent
        }
        if (itemSelectedEvent(i1, i2) is EditMasterEvent ) {
          // do if EditMasterEvent
        }
      }
    }
    

    请考虑以下内容:

    abstract class EditEvent extends Equatable {
      const EditEvent();
    
      void doStuff();
    }
    
    class EditItemDeselected extends EditEvent {
      EditItemDeselected(this.outerIdx, this.innerIdx);
      final int outerIdx, innerIdx;
    
      void doStuff() {
        // do if EditEvent
      }
    
      @override
      List<Object?> get props => [outerIdx, innerIdx];
    }
    
    class EditMasterItemDeselected extends EditEvent {
      EditMasterItemDeselected(this.outerIdx, this.innerIdx);
      final int outerIdx, innerIdx;
    
      void doStuff() {
        // do if EditMasterEvent
      }
    
      @override
      List<Object?> get props => [outerIdx, innerIdx];
    }
    
    class ChildWidget {
      ChildWidget(this.itemSelectedEvent);
    
      final Function(int, int) itemSelectedEvent;
    
      void func(int i1, int i2) {
        itemSelectedEvent(i1, i2).doStuff()
      }
    }