收益率延迟迭代问题 [英] Yield return deferred iteration problems

查看:143
本文介绍了收益率延迟迭代问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道yield return会利用延迟加载,但我想知道我是否可能滥用迭代器或者很可能需要重构器。

I know that yield return takes advantage of lazy loading but I'm wondering if I might be misusing the iterator or quite possibly need a refactor.

我的递归迭代器method返回给定 PageNode 的所有祖先,包括 pageNode 本身。

My recursive iterator method returns all the ancestors of a given PageNode including the pageNode itself.

public class PageNodeIterator {
    //properties and constructor left out for brevity

    public IEnumerable<IPageNode> ancestorsOf(IPageNode pageNode) {
        if(pageNode == null) throw new ArgumentNullException(("pageNode"));

        if (pageNode.url != pageNodeService.rootUrl) {
            yield return pageNode;
            if (pageNode.parent != null)
                foreach (var node in ancestorsOf(pageNode.parent))
                    yield return node;
        }
    }
}

在我打电话给 ancestorsOf ,我正在调用该方法然后反转返回的 IEnumerable 的顺序,但由于加载是延迟的,因此调用不会直到我在下一行调用 ToArray(),然后我的迭代器方法中的 pageNodeService 才真正发生返回null并抛出空引用异常。

In my call to ancestorsOf, I'm calling the method and then reversing the order of the returned IEnumerable, but since loading is deferred the call doesn't actually happen until I call ToArray() on the next line and at that point pageNodeService in my iterator method is null and a null reference exception is thrown.

ancestors = pageNodeIterator.ancestorsOf(currentNode).Reverse();
return ancestors.ToArray()[1].parent.children;

所以,我想知道我哪里出错了。在这种情况下使用迭代器的正确方法是什么呢?

So, I'm wondering where I've gone wrong. What would be the proper way to use an iterator in this case, if at all?

我也想知道为什么 pageNodeService 在执行时为空。即使执行被推迟,它还不应该保持价值吗?

I'm also wondering why pageNodeService is null at the time of execution. Even the execution is deferred shouldn't it still hold a value?

推荐答案

不是真正的答案...更多关于消除递归的替代实现的建议。发表评论的时间太长。

Not really an answer... more of a suggestion for an alternative implementation that eliminates recursion. Too long to post as a comment.

    public IEnumerable<IPageNode> ancestorsOf(IPageNode pageNode) {
        if(pageNode == null) throw new ArgumentNullException(("pageNode"));
        Stack<IPageNode> stack = new Stack<IPageNode>();
        stack.Push(pageNode);
        while(stack.Any())
        {
            IPageNode n=stack.Pop();
            if (n.url != pageNodeService.rootUrl) {
                yield return n;
                if(n.parent != null)
                {
                    stack.Push(n.parent);
                }
            }
        }
    }

思考关于它,你可以完全删除堆栈:

Thinking about it, you could remove the Stack altogether:

public IEnumerable<IPageNode> ancestorsOf(IPageNode pageNode) {
    if(pageNode == null) throw new ArgumentNullException(("pageNode"));
    IPageNode n = pageNode;
    while(n != null && n.url != pageNodeService.rootUrl)
    {
        yield return n;
        n = n.parent;
    }
}

这篇关于收益率延迟迭代问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆