Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# “编辑列表”包含对象,而对象本身包含对象,依此类推_C#_Linq_List - Fatal编程技术网

C# “编辑列表”包含对象,而对象本身包含对象,依此类推

C# “编辑列表”包含对象,而对象本身包含对象,依此类推,c#,linq,list,C#,Linq,List,我对对象列表有问题 此列表包含本身包含对象的对象,以此类推。。。(所有对象均为同一类型) 我的对象如下所示: public class MyObject (...) { ... public MyObject[] Object; ... } 我想更改这些对象的一些变量(根据某些参数),我认为使用LINQ可以做到这一点 我的问题是,我真的不知道如何做一些将通过所有递归列表的事情,而不管它们的级别如何 我希望我尽可能清楚 提前感谢您的帮助。您可以编写一个简单的递

我对对象列表有问题

此列表包含本身包含对象的对象,以此类推。。。(所有对象均为同一类型)

我的对象如下所示:

  public class MyObject (...)
  {
    ...
    public MyObject[] Object;
    ...
  }
我想更改这些对象的一些变量(根据某些参数),我认为使用LINQ可以做到这一点

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

我希望我尽可能清楚


提前感谢您的帮助。

您可以编写一个简单的递归方法来轻松地执行您想要的操作:

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);
    }
}
static void AddRecursively(MyObject obj, List<MyObject> listToAddTo)
{
  listToAddTo.Add(obj);
  foreach (var o in obj.Object)
    AddRecursively(o, listToAddTo);
}

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

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;
            }
        }
    }
}

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

可能就是这样:

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);
    }
}
static void AddRecursively(MyObject obj, List<MyObject> listToAddTo)
{
  listToAddTo.Add(obj);
  foreach (var o in obj.Object)
    AddRecursively(o, listToAddTo);
}
静态void递归添加(MyObject对象,列表列表添加到)
{
listToAddTo.Add(对象);
foreach(对象对象中的变量o)
递归添加(o,listToAddTo);
}

我建议使用此扩展方法,将操作递归应用于所有项

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

第一个参数告诉
ForEach
如何访问嵌套对象。第二个参数告诉我们如何处理每一项。

@lazyberezovsky他在OP中引用了“递归”,所以我认为他熟悉这个术语。对不起,我的错-在OP中没有注意到这一点
myObjectList.ForEach(x => x.Object, x => x.Value = "new value");