【问题标题】:Force yield return method to throw exception at time of calling [duplicate]强制收益返回方法在调用时抛出异常[重复]
【发布时间】:2017-10-26 13:31:38
【问题描述】:

我继承了一个方法,它返回一个 IEnumerable<whatever>,并通过 yield return myWhatever 构造实现:

public IEnumberable<whatever> GetWhatevers() {
    while (true) {      
        // do calculations
        yield return myWhatever
    }
}

我发现了一个错误,如果该类的集合之一为空,它会导致无限循环,因此我添加了一个检查并编写了一个测试:

public IEnumberable<whatever> GetWhatevers() {

    if (_dependentList == null || _dependentList.Count == 0) {
        throw new InvalidOperationException("Unable to process without whatevers");
    }

    while (true) {      
        // do calculations
        yield return myWhatever
    }
}

void MyWhateverThrowsIOEOnEmptyList() {
    var sut = new MyThing(null);
    Assert.ThrowsException<InvalidOperationException>(() => {
        var results = sut.GetWhatevers();
    });
}

我现在意识到这个测试失败了,因为即使我调用了该方法(由于 yield 构造),我也从未真正开始迭代结果。

我可以通过这样做来修复测试:

void MyWhateverThrowsIOEOnEmptyList() {
    var sut = new MyThing(null);
    Assert.ThrowsException<InvalidOperationException>(() => {
        var results = sut.GetWhatevers().ToList();
    });
}

...但我不喜欢它。这意味着无论调用者调用此方法,在尝试访问结果之前,他们都不知道其中隐藏了一个 IOE。这个结果变量可能会往返于 Timbucktu,但始终不知道它是一个定时炸弹。

所以现在,每当我使用这种方法时,我必须记住其中可能潜伏着一个异常。

这个方法太复杂了,我不想用传统的循环重写。有没有一种方法可以强制在“调用时”而不是在“解决时”抛出异常,以便在调用时知道存在问题?

【问题讨论】:

  • (这个丑陋的小副作用似乎不值得yield...)
  • 您可以将yield return 代码放入private GetWhateversInternal() 并让公众GetWhatevers() 进行检查,然后return GetWhateversInternal();
  • 迭代器只有一件有用的事情。他们会迭代它,保证。无论你使用 ToList() 还是 foreach 或调用 MoveNext() 都无所谓,都一样。
  • @HansPassant - 我没有意识到这本身就是一个迭代器(第一次处理yield),但我认为我们即将对我们的命名约定进行微调!

标签: c# exception yield-return


【解决方案1】:

从另一个调用迭代器方法:

public IEnumerable<Whatever> GetWhatevers(){
    if (_dependentList == null || _dependentList.Count == 0) {
        throw new InvalidOperationException("Unable to process without whatevers");
    }

    return GetWhatevers_Impl();
}

private IEnumerable<Whatever> GetWhatevers_Impl(){
     while (true) {      
        // do calculations
        yield return myWhatever
    }
}

【讨论】:

  • Herp-a-derpa,这将是关键。我会把它给你,因为你先回答了,但也感谢其他人。
猜你喜欢
  • 2017-06-28
  • 2020-12-16
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 2013-01-22
  • 2010-12-15
  • 1970-01-01
相关资源
最近更新 更多