如何将递归对象转换为C#中的集合?
我有一个递归对象,链表真:如何将递归对象转换为C#中的集合?
public class LinkedList
{
public string UniqueKey { get; set; }
public LinkedList LinkedList { get; set; }
}
的LinkedList会有一些对象图将在LinkedList.LinkedList最终结束== NULL。
我想将图中的所有对象放到LinkedList集合中,以便我可以遍历它们。我如何在C#中执行此操作?我觉得好像有一个非常简单的方法来使用yield或Linq voodoo来做这件事情?
像这样的东西应该工作。如果你能控制课程,你可以直接使用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
。
这是你想要的吗?
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;
}
}
}
这不是非常有效。对于包含100个项目的列表,您将创建100个枚举器,最后一个项目在返回给调用者之前必须先通过所有项目。 – Guffa 2010-07-18 02:04:37
有没有很好的LINQ方法标准.NET库,允许一些优雅的LINQ巫术,但你可以从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);
}
}
这真棒,但不幸的是我不能添加任何其他库到项目中。我将在未来的产品上使用它! – 2010-07-18 03:02:41
@Geoffrey:您可以将'Generate'方法添加到您的项目中(这只是3行代码)。 – 2010-07-18 03:12:38
啊,这是正确的。除非逐字回答问题,否则它应该是'yield return l'而不是'yield return l.UniqueKey'吧?所有这一切对于OP来说应该很容易就能把那部分弄清楚。 – 2010-07-18 03:06:34