【问题标题】:My recursive function skips over calling itself for some reason我的递归函数由于某种原因跳过了自己的调用
【发布时间】:2018-10-08 07:14:37
【问题描述】:

我确信有更好的方法可以做到这一点,但我只是想知道为什么这不起作用。调试时,调试器会跳过 GetAllChildren(

    public static IEnumerable<DependencyObject> GetAllChildren(DependencyObject d)
    {
        if (d.GetType().GetProperties().Any(p => p.Name == "Content"))
        {
            var v = (DependencyObject)(d.GetType().GetProperty("Content").GetValue(d));
            GetAllChildren(v);
            yield return v;
        }
        if (d.GetType().GetProperties().Any(p => p.Name == "Children"))
        {
            foreach (DependencyObject v in (UIElementCollection)d.GetType().GetProperty("Children").GetValue(d))
            {
                yield return v;
                GetAllChildren(v);
            }
        }
    }

【问题讨论】:

  • 请仔细阅读yield return的作用。

标签: c# wpf recursion yield-return


【解决方案1】:

这是因为您在 IEnumerable 中使用了 yield return。

一旦你迭代你的函数的结果,代码就会被执行。这称为惰性求值,也是 LINQ 的一个关键方面。要了解延迟执行,请阅读this

其实,你又犯了一个错误。您的代码甚至不会返回递归调用的结果。你不会用它做任何事情。你必须这样做:

yield return v;
foreach (var child in GetAllChildren(v))
{
  yield return child;
}

【讨论】:

  • 没有。您似乎不了解 IEnumerable 的基础知识,因此我建议您阅读它。简而言之,IEnumerable 表示您可以对其进行迭代。它只有一个功能,即GetEnumerator。该枚举器有一个 foreach 循环“使用”的 moveNext 函数。将返回类型更改为枚举器基本上对您没有任何好处,而是限制了您。通常你不会返回一个枚举数。
猜你喜欢
  • 2020-10-02
  • 1970-01-01
  • 2011-06-03
  • 1970-01-01
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-20
相关资源
最近更新 更多