如何将递归对象转换为C#中的Collection?

时间:2010-07-18 01:18:08

标签: c# linq generics collections

我有一个递归对象,一个真正的链表:

public class LinkedList 
{
    public string UniqueKey { get; set; }
    public LinkedList LinkedList { get; set; }
}

LinkedList将有一些最终以LinkedList.LinkedList == null结尾的对象图。

我想获取图中的所有对象并将它们放入LinkedList集合中,以便我可以迭代它们。我如何在C#中执行此操作?我觉得好像有一种非常简单的方法可以使用yield或Linq voodoo来解决这个问题?

3 个答案:

答案 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);
  }
}