有没有办法在通用地图中使用 Streamcontroller?

Is there any way to use Streamcontroller in generic map?

更新评论

原问题

我正在尝试制作一个状态广播器,它通过单一路径向听众广播一些价值。 并且想使用泛型来减少重复的逻辑。

以下是我正在尝试的。

import 'dart:async';

class StateBroadcaster {
  final _sinkMap = <Type, StreamController<dynamic>>{
    StudyTimerStatus: StreamController<StudyTimerStatus?>.broadcast(),
  };

  void notify<T>(T value) => _sinkMap[T]?.add(value);

  StreamSubscription<T> listen<T>(void Function(T) onData) {
    return (_sinkMap[T] as StreamController<T>).stream.listen(onData);
  }
}

但是当我运行这段代码时,运行时间错误出现在(_sinkMap[T] as StreamController<T>)

The following _CastError was thrown building Builder: type '_AsyncBroadcastStreamController<StudyTimerStatus?>' is not a subtype of type 'StreamController' in type cast

我该如何解决这个问题?

如果能达到我想要的目标(广播数据),改代码就好了。

我也试过省略向上转换,但是编译错误来了。

return _sinkMap[T].stream.listen(onData);

A value of type 'StreamSubscription' can't be returned from the method 'listen' because it has a return type of 'StreamSubscription'

The argument type 'void Function(T)' can't be assigned to the parameter type 'void Function(dynamic)?

我认为这应该可以满足您的要求。

如果您使用 listen<T>() 订阅,那么您应该将类​​型 T 的相应值传递给 notify

import 'dart:async';

class StateBroadcaster {
  final _sinkMap = <Type, StreamController<dynamic>>{};

  void notify<T>(T value) {
    _sinkMap[T] ??= StreamController<T>.broadcast();
    _sinkMap[T]?.add(value);
  }

  StreamSubscription<T> listen<T>(void Function(T) onData) {
    _sinkMap[T] ??= StreamController<T>.broadcast();
    return (_sinkMap[T] as StreamController<T>).stream.listen(onData);
  }
}

void main() {
  final broadcaster = StateBroadcaster();
  broadcaster.listen<int>((v) => print('int: $v'));
  broadcaster.listen<String>((v) => print('String: $v'));
  broadcaster.notify(1);
  broadcaster.notify('a');
  broadcaster.notify(2);
  broadcaster.notify('b');
  broadcaster.notify(3);
  broadcaster.notify('c');
}

如果您想在 _sinkMap 中定义键值对而不是根据需要创建 key/value 对,这应该是可行的,但是如果您尝试使用地图中未预定义的键。

另外,您需要决定流值是否应该可以为空。如果您希望它们可以为空,则需要在 listen.

中的类型中添加一个 ?
import 'dart:async';

class StateBroadcaster {
  final _sinkMap = <Type, StreamController<dynamic>>{
    StudyTimerStatus: StreamController<StudyTimerStatus?>.broadcast(),
  };

  void notify<T>(T value) => _sinkMap[T]?.add(value);

  StreamSubscription<T?> listen<T>(void Function(T) onData) {
    return (_sinkMap[T] as StreamController<T?>).stream.listen(onData);
  }
}

如果您不希望它们可以为空,则需要从 _sinkMap

中的类型中删除 ?
import 'dart:async';

class StateBroadcaster {
  final _sinkMap = <Type, StreamController<dynamic>>{
    StudyTimerStatus: StreamController<StudyTimerStatus>.broadcast(),
  };

  void notify<T>(T value) => _sinkMap[T]?.add(value);

  StreamSubscription<T> listen<T>(void Function(T) onData) {
    return (_sinkMap[T] as StreamController<T>).stream.listen(onData);
  }
}