3

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

此列表包含本身包含对象的对象,依此类推...(所有对象都属于同一类型)

我的对象看起来像这样:

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

我想更改这些对象的一些变量(根据某些参数),并且我认为使用 LINQ 来做到这一点。

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

我希望我尽可能清楚。

预先感谢您的帮助。

4

4 回答 4

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";
}
于 2012-11-27T21:20:04.580 回答
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
}

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

于 2012-11-27T21:24:59.700 回答
1

也许只是这样的事情:

static void AddRecursively(MyObject obj, List<MyObject> listToAddTo)
{
  listToAddTo.Add(obj);
  foreach (var o in obj.Object)
    AddRecursively(o, listToAddTo);
}
于 2012-11-27T21:28:58.407 回答
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如何访问嵌套对象。第二个参数告诉如何处理每个项目。

于 2012-11-27T21:36:52.450 回答