代码之家  ›  专栏  ›  技术社区  ›  David

嵌套方法中的屈服

  •  17
  • David  · 技术社区  · 15 年前

    如果我单步执行以下代码,将跳过对returnOne()的调用。

    static IEnumerable<int> OneThroughFive()
    {
        ReturnOne();
        yield return 2;
        yield return 3;
        yield return 4;
        yield return 5;
    }
    
    static IEnumerator<int> ReturnOne()
    {
        yield return 1;
    }
    

    我只能假设编译器正在剥离它,因为我所做的操作无效。我希望能够将我的枚举分离到各种方法中。这有可能吗?

    1 回复  |  直到 15 年前
        1
  •  30
  •   Jon Skeet    15 年前

    你实际上没有使用 ReturnOne . 您正在调用该方法,忽略返回值…这意味着你永远不会看到你的代码在运行。你 可以 这样做:

    static IEnumerable<int> OneThroughFive()
    {
        foreach (int x in ReturnOne())
        {
            yield x;
        }
        yield return 2;
        yield return 3;
        yield return 4;
        yield return 5;
    }
    

    C没有(目前至少是:)有一种“yield all”结构。

    事实上,你没有进入它,这与你在一个迭代器块中有一个调用无关,直到你开始 使用 迭代器块的结果,所有代码都不运行。这就是为什么你需要把论证验证和让步分开的原因。例如,考虑以下代码:

    public IEnumerator<string> ReturnSubstrings(string x)
    {
        if (x == null)
        {
             throw ArgumentNullException();
        }
        for (int i = 0; i < x.Length; i++)
        {
             yield return x.Substring(i);
        }
    }
    ...
    ReturnSubstring(null); // No exception thrown
    

    你需要这样写:

    public IEnumerator<string> ReturnSubstrings(string x)
    {
        if (x == null)
        {
             throw ArgumentNullException();
        }
        return ReturnSubstringsImpl(x);
    }
    
    private IEnumerator<string> ReturnSubstringsImpl(string x)
    {
        for (int i = 0; i < x.Length; i++)
        {
             yield return x.Substring(i);
        }
    }
    

    欲了解更多详情,请阅读C的第6章-这恰好是第一版的免费章节:) Grab it here .