我有一个递归对象,一个真正的链表:
public class LinkedList
{
public string UniqueKey { get; set; }
public LinkedList LinkedList { get; set; }
}
LinkedList将有一些最终以LinkedList.LinkedList == null结尾的对象图。
我想获取图中的所有对象并将它们放入LinkedList集合中,以便我可以迭代它们。我如何在C#中执行此操作?我觉得好像有一种非常简单的方法可以使用yield或Linq voodoo来解决这个问题?
答案 0 :(得分:2)
这样的事情应该有效。如果您可以控制课程,则可以直接IEnumerable
。
public class LinkedListEnumerable : IEnumerable<string>
{
LinkedList list;
public LinkedListEnumerable(LinkedList l)
{
this.list = l;
}
public IEnumerator<string> GetEnumerator()
{
LinkedList l = list;
while(l != null)
{
yield return l.UniqueKey;
l = l.Next;
}
}
}
然后你可以用for-each循环迭代LinkedListEnumerable
。
答案 1 :(得分:0)
这是你想要的吗?
public class LinkedList
{
public string UniqueKey { get; set; }
public LinkedList LinkedList { get; set; }
public IEnumerable<LinkedList> GetAllNodes()
{
if (LinkedList != null)
{
yield return LinkedList;
foreach (var node in LinkedList.GetAllNodes())
yield return node;
}
}
}
答案 2 :(得分:0)
标准.NET库中没有很好的LINQ方法允许一些优雅的LINQ voodoo,但你可以使用MoreLINQ项目中的Generate
方法并写下这个:
Enumerable
.Generate(list, l => l.LinkedList)
.TakeWhile(l => l != null).Select(l => l.UniqueKey);
它使用Generate
来创建所有元素的“无限”列表 - 它实际上并不是无限的,因为它是懒惰生成的,一旦我们在最后找到null
值,我们就会停止使用它(使用TakeWhile
)。然后我们使用Select
返回一系列值(而不是链表节点)。
这实际上是表达由Matthew发布的while
循环解决方案的一种很好的声明方式(它应该具有大致相似的性能)。
编辑 Generate
方法如下所示:
IEnumerable<T> Generate(T current, Func<T, T> generator) {
while(true) {
yield return current;
current = generator(current);
}
}