编辑列表包含自身包含对象的对象,依此类推

时间:2012-11-27 21:14:53

标签: c# linq list

我对象列表有问题......

此List包含自身包含对象的对象,依此类推......(所有对象属于同一类型)

我的对象看起来像这样:

  public class MyObject (...)
  {
    ...
    public MyObject[] Object;
    ...
  }

我想更改这些对象的一些变量(根据某些参数),为此我想使用LINQ。

我的问题是,我真的不知道如何做一些会通过我的所有递归列表的事情,无论他们的等级如何。

我希望我尽可能清楚。

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:3)

你可以写一个简单的递归方法来做你想做的事情:

public static void Touch(MyObject obj, string otherParameter)
{
    obj.Value = otherParameter;
    foreach (var child in obj.Object)
    {
        Touch(child, otherParameter);
    }
}

如果你真的想要一个更加LINQ式的方法,或者你经常需要一个更通用的方法,你可以使用这样的东西:

public static IEnumerable<T> FlattenTree<T>(IEnumerable<T> source, Func<T, IEnumerable<T>> selector)
{
    //you could change this to a Queue or any other data structure 
    //to change the type of traversal from depth first to breath first or whatever
    var stack = new Stack<T>(); 
    while (stack.Any())
    {
        T next = stack.Pop();
        yield return next;
        foreach (T child in selector(next))
            stack.Push(child);
    }
}

然后您就可以使用它:

MyObject root = new MyObject();

var allNodes = FlattenTree(new[] { root }, node => node.Object);
foreach (var node in allNodes)
{
    node.Value = "value";
}

答案 1 :(得分:3)

您可以使用此递归扩展方法:

public static IEnumerable<T> Traverse<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> fnRecurse)
{
    foreach (T item in source)
    {
        yield return item;

        IEnumerable<T> seqRecurse = fnRecurse(item);
        if (seqRecurse != null)
        {
            foreach (T itemRecurse in Traverse(seqRecurse, fnRecurse))
            {
                yield return itemRecurse;
            }
        }
    }
}

您可以这样使用它:

var allObj = list.Traverse(o => o.Object);
foreach (MyObject o in allObj)
{ 
    // do something
}

它很方便,因为它是通用的,适用于任何类型,也因为它使用延迟执行。

答案 2 :(得分:1)

也许只是这样的事情:

static void AddRecursively(MyObject obj, List<MyObject> listToAddTo)
{
  listToAddTo.Add(obj);
  foreach (var o in obj.Object)
    AddRecursively(o, listToAddTo);
}

答案 3 :(得分:1)

我建议使用这种递归方法,以递归方式对所有项目执行操作

public static void ForEach<T>(this IEnumerable<T> source,
                              Func<T, IEnumerable<T>> getChildren,
                              Action<T> action)
{
    if (source == null) {
        return;
    }
    foreach (T item in source) {
        action(item);
        IEnumerable<T> children = getChildren(item);
        children.ForEach(getChildren, action);
    }
}

您可以像这样将它应用到您的列表中

myObjectList.ForEach(x => x.Object, x => x.Value = "new value");

第一个参数告诉ForEach如何访问嵌套对象。第二个参数说明了如何处理每个项目。