gpt4 book ai didi

c# - yield 递延迭代问题

转载 作者:太空宇宙 更新时间:2023-11-03 17:17:22 26 4
gpt4 key购买 nike

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

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

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 并引发空引用异常。

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

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

我也想知道为什么pageNodeService在执行的时候是null。即使执行被推迟,它不应该仍然有值(value)吗?

最佳答案

我不知道你的错误在哪里,StackOverflow 不是调试你代码的服务;我会通过在调试器中运行它并查找错误来解决您的问题。

但是我会借此机会指出这一点:

public IEnumerable<IPageNode> AncestorsOf(IPageNode pageNode) {
if(pageNode == null) throw new ArgumentNullException(("pageNode"));
// Do stuff that yields

有点问题,因为在第一次调用 MoveNext 之前, block 中的所有代码都不会运行。换句话说,如果您这样做:

var seq = AncestorsOf(null); // Not thrown here!
using (var enumtor = seq.GetEnumerator())
{
bool more = enumtor.MoveNext(); // Exception is thrown here!

这让人们非常惊讶。而是像这样编写代码:

public IEnumerable<IPageNode> AncestorsOf(IPageNode pageNode) {
if(pageNode == null) throw new ArgumentNullException(("pageNode"));
return AncestorsOfIterator(pageNode);
}
private IEnumerable<IPageNode> AncestorsOfIterator(IPageNode pageNode)
{
Debug.Assert(pageNode != null);
// Do stuff that yields
}

关于c# - yield 递延迭代问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17814039/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com