【问题标题】:Named Iterator & Exceptions命名迭代器和异常
【发布时间】:2009-07-19 08:55:44
【问题描述】:

我正在编写一个需要检查一些参数的方法,如果它们被验证,则返回一个 IEnumerable。例如

public static IEnumerable<double> GetEnum(int param)
{
    if (!IsValidParameter(param))
    {
        throw new Exception();
    }

    while(true)
    {
        yield return 5.0;
    }
}

但是,我相信由于延迟评估,当我使用错误参数运行单元测试,但还没有调用任何 IEnumerable 方法时,不会抛出异常。

[Test]
[ExpectedException(typeof(Exception))]
void Test()
{
    var ie = GetEnum(bad_param);
}

我可以通过在另一个函数(比如 Foo)中构建 IEnumerable 来解决问题,然后检查 GetEnum 中的参数并调用 Foo,但有没有无需创建多个函数的解决方案?

干杯,尤尔根

【问题讨论】:

    标签: c# exception iterator


    【解决方案1】:

    由于迭代器块的定义方式,您目前需要两种方法来实现:

    public static IEnumerable<double> GetEnum(int param) {
        if (!IsValidParameter(param)) {
            throw new Exception();
        }
        return GetEnumCore(param);
    }
    private static IEnumerable<double> GetEnumCore(int param) {
        while(true) {
            yield return 5.0;
        }
    }
    

    只有迭代器块 (GetEnumCore) 被延迟; GetEnum 立即运行,执行您的检查。

    【讨论】:

    • 我实际上想知道编译器是否足够聪明,可以将两种方法都简化为一个迭代器块。谢谢你的提示,马克。
    【解决方案2】:

    您可以使用底层枚举器启动迭代吗?

    [Test]
    [ExpectedException(typeof(Exception))]
    void Test()
    {
        var ie = GetEnum(bad_param);
        var en = ie.GetEnumerator();
        en.MoveNext();
    }
    

    【讨论】:

    • 我理解枚举器这种懒惰的行为,之前有没有办法抛出异常?在为命名迭代生成的类的构造函数中说?
    【解决方案3】:

    只要你不开始枚举你的方法就永远不会被调用。您可以尝试在测试中枚举:

    var ie = GetEnum(bad_param).First();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 2020-01-15
      相关资源
      最近更新 更多