【问题标题】:Is this abusing the IEnumerator construct?这是在滥用 IEnumerator 构造吗?
【发布时间】:2012-06-13 19:08:08
【问题描述】:

我有一个Sensor 状态机,为此我编写了Cycle() 方法:

  /// <summary>
  /// Cycle sets the machine to follow a path from one it's current state to the next. The 
  /// behavior of the sensor is to revert to it's default state should an invalid state be
  /// encountered.
  /// </summary>
  /// <returns></returns>
  public IState Cycle() {
     if(_currentState.Next.IsNullOrEmpty()) {
        _currentState = DefaultState.Set();
     } else {
        _currentState = _currentState.Cycle();
     }
     return _currentState;
  }

  public IEnumerator<IState> Cycle(Func<bool> HasWork) {
     while(HasWork()) {
        yield return Cycle();
     }
  }

实施:

  [TestMethod]
  public void SensorExperiment_CycleWhileFunc() {
     float offset = .5f;
     IState previousState = State.Empty;

     IStimulus temp = new PassiveStimulus(68f) {
        Offset = offset
     };
     ISensor thermostat = new Sensor(65f, 75f, temp);

     int cycles = 0;
     // using this func to tell the machine when to turn off
     Func<bool> hasWork = () => {
        previousState = thermostat.CurrentState;
        // run 10 cycles6
        return cycles++ < 10;
     };

     var iterator = thermostat.Cycle(hasWork);

     while(iterator.MoveNext()) {
        Console.WriteLine("Previous State: {0}\tCurrent State: {1}",
           previousState.Name, iterator.Current.Name);
     }
  }

我已阅读Eric Lippert's answer 以使用 IEnumerator as 状态机进行查询。 我的实现是否滥用或利用了 IEnumerator? 我将我的实现视为提供一系列状态自动化的一种方式。

【问题讨论】:

  • 考虑到状态机的生成方式可能在未来发生变化。
  • @Oded:不确定我是否关注。 Sensor 是抽象 Machine 的特化,方法由适当的接口定义。
  • 好的。当您在代码中使用yield 时,编译器会生成一个状态机。此状态机的工作方式可能在未来版本中发生变化,并且可能如果它依赖于它的工作方式会破坏您的代码。
  • @Oded 在我看来,这段代码不依赖于yield 的任何实现细节。我认为它是安全的。
  • @IAbstract - 嗯......可能。人们希望实施它的 MS 团队能够进行足够好的测试以覆盖大多数基础。但是人们确实有创意;)

标签: c# .net yield state-machine ienumerator


【解决方案1】:

我不认为这样使用它真的是一种滥用,毕竟你把结果当成一个集合。

另一方面,我看不出你应该在这里使用迭代器的任何理由。如果您将代码重写为以下内容,它应该可以正常工作。

while (hasWork())
    Console.WriteLine("Previous State: {0}\tCurrent State: {1}",
       previousState.Name, thermostat.Cycle().Name);

【讨论】:

    猜你喜欢
    • 2011-04-07
    • 1970-01-01
    • 2011-01-14
    • 2010-12-04
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    • 2010-12-05
    • 2017-03-17
    相关资源
    最近更新 更多