对于该List对象,我们有一个名为Reverse()的方法.
它反转了"就地"列表的顺序,它不会返回任何内容.
对于该IEnumerable对象,我们有一个名为Reverse()的扩展方法.
它返回另一个IEnumerable.
我需要在列表中以相反的顺序迭代,所以我不能直接使用第二种方法,因为我得到一个List,我不想反转它,只是向后迭代.
所以我可以这样做:
for(int i = list.Count - 1; i >=0; i--)
Run Code Online (Sandbox Code Playgroud)
要么
foreach(var item in list.AsEnumerable().Reverse())
Run Code Online (Sandbox Code Playgroud)
我发现它的可读性低于我拥有IEnumerable时的可读性
foreach(var item in list.Reverse())
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么这两种方法以这种方式实现,具有相同的名称.这很令人讨厌和困惑.
为什么没有一个名为BackwardsIterator()的扩展名在Reverse()的地方为所有IEnumerable工作?
我对这种选择的历史原因非常感兴趣,而不是"怎么做"的东西!
几年前,有人抱怨实施,Linq.Reverse()微软承诺解决这个问题.这是在2008年,所以问题是,框架4是否有一个优化的实现,Linq.Reverse()当集合类型允许时(例如IList<T>),没有实现集合(即将所有元素复制到内部数组)?
我知道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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我的调用中ancestorsOf,我正在调用方法然后反转返回的顺序IEnumerable,但是由于加载是延迟的,所以调用实际上不会发生,直到我调用ToArray()下一行并且pageNodeService在我的迭代器方法中的那个点为null并且抛出空引用异常.
ancestors = pageNodeIterator.ancestorsOf(currentNode).Reverse();
return ancestors.ToArray()[1].parent.children;
Run Code Online (Sandbox Code Playgroud)
所以,我想知道我哪里出错了.在这种情况下,如果有的话,使用迭代器的正确方法是什么?
我也想知道为什么pageNodeService在执行时为空.即使执行被延期,它还不应该保持价值吗?
我想反转堆栈,因此顶部的元素应该为零,反之亦然。我知道这样做可能不是正确的操作,但我想这样做。如果没有,我想知道为什么这不起作用
当我做
List<string> MyList = new List<string>();
MyList.Reverse()
Run Code Online (Sandbox Code Playgroud)
有用。但不是这个。
Stack<string> MyStack = new Stack<string>();
MyStack.Reverse()
Run Code Online (Sandbox Code Playgroud)
有什么想法/解决方案吗?
感谢和问候,
加内什