强制yield return方法在调用时抛出异常



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

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

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

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。由此产生的变量可能会往返于廷巴克图,而永远不知道这是一颗定时炸弹。

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

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

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

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
}
}

最新更新