【问题标题】:Wrapping call to iterator in try/catch when using yield使用 yield 时在 try/catch 中包装对迭代器的调用
【发布时间】:2016-05-22 04:39:06
【问题描述】:

我需要在我作为迭代器(使用yield)实现的方法中执行一些繁重、有些脆弱的逻辑:

public IEnumerable<Things> GetMoreThings() {
    while (goodStuffHappens()) {
        Things moreThingsIWant = TemptFateAgain();
        if (moreThingsIWant.Any())
            yield return moreThingsIWant;
    }
}

在调用方法中,我需要将对GetMoreThings的调用包装在try/catchyield return结果中:

try {
    foreach (Things thing in Helpful.GetMoreThings())
        yield return thing;
}

catch (Exception e) {
    //crash, burn
}

发起者会立即意识到这是不可能的——there is no such thing as a yield inside a try/catch block(仅限try/finally)。

有什么建议吗?

【问题讨论】:

  • 你真的想忽略异常,还是catch 块中有一些你没有显示的代码?
  • 是的,那里有重要的代码

标签: c# try-catch yield-return


【解决方案1】:

这里的两个答案都是正确的。这个没有内置的快捷方式,您需要在while 而不是for 循环中梳理迭代器,以便区分对Enumerator.MoveNext() 的调用和Enumerator.Current 的使用。

IEnumerator<Things> iterator = Helpful.GetMoreThings.GetEnumerator();
bool more = true;

while (more) {
    try {
        more = iterator.MoveNext();
    }
    catch (Exception e) {
        //crash, burn
    }

    if (more)
        yield return iterator.Current;
}

【讨论】:

    【解决方案2】:

    Helpful.GetMoreThings() 调用和枚举与yield 分开放置:

    try {
        var results = Helpful.GetMoreThings().ToList();
    }
    catch (Exception e) {
        //crash, burn
    }
    
    foreach (Things thing in results)
        yield return thing;
    

    类似的东西。

    如果你想让它变得懒惰,代码会变得非常讨厌。您不能再使用foreach。您需要手动编写迭代循环,代码量会激增到 20 行,难以辨认。我知道,因为我昨天做了这个。

    【讨论】:

    • 是的,我需要它变得懒惰。否则我很难找到一个很好的理由来设计它。
    • 然后,按照最后一段所说的进行:将 foreach 扩展为手动编写的循环。然后,您可以调用 MoveNext() 并使用 catch 保护并在没有 catch 的情况下让出。
    【解决方案3】:

    您可以使用the Catch() extension method from Ix.Net,或直接复制its Apache-licensed source code。代码可能如下所示:

    return Helpful.GetMoreThings().Catch((Exception e) =>
    {
        // crash, burn
        return null;
    }
    

    【讨论】:

    • 源代码实际上是上面@usr的答案中提到的20个难以辨认的混乱行。
    猜你喜欢
    • 2013-09-20
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    • 2017-02-15
    • 2012-11-15
    • 2021-10-16
    • 2021-11-25
    • 1970-01-01
    相关资源
    最近更新 更多