递归收益 [英] yield return in recursion

查看:83
本文介绍了递归收益的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建

    IEnumrable<PropertyInfo> 

iv有一个名为Disassemble的方法,该方法递归地迭代抛出给定对象及其属性的所有子对象.

iv'e got a method called Disassemble which iterates recursively throw a given object and all it's child objects of it's properties .

请不要担心自己与INameValueWrapper类型的内部包装对象有关

下面的问题是当我遇到一个属类的属性时,我也不想在其上调用反汇编 并将其添加到IEnumrable的同一迭代中,Dissasemble在被调用时不会再次发生 我在哪里发表评论: //问题在这里.

The problem below is when i encounter a property which is a Class i wan't to call Disassemble on it as well and add it to the same iteration of the IEnumrable , the Dissasemble does not occur again when it is called where i put the comment : // The problem is here .

    public static IEnumerable<T> Dissasemble<T>(this object sourceObj) where T : INameValueWrapper
    {
        var properties = sourceObj.GetType().GetProperties();

        foreach (var prop in properties)
        {
            var wrapper = (T)prop.WrapPropertyInfo(sourceObj);
            yield return wrapper;

            if (wrapper is CollectionPropertyInfoWrapper)
            {
                var colWrapper = wrapper as CollectionPropertyInfoWrapper;
                var collection = (IList)colWrapper.Value;

                int index = 0;
                foreach (var item in collection)
                {
                    yield return (T)item.WrapItem(collection, index + 1);
                    index++;
                }
            }
            else
            {
                var propWrapper = wrapper as PropertyInfoWrapper;
                if (!propWrapper.IsPrimitive)
                {
                    var childObject = prop.GetValue(sourceObj);
                    childObject.Dissasemble<T>(); // here is the problem 
                }
            }
        }

        yield break;
    } 

1)为什么不调用它并将其添加到迭代中?

1) Why does it not get called and added to the iteration ?

2)解决此问题的方法是什么? ,

2) What is the work around this issue ? ,

 i could call childObject.Dissasemble<T>().ToList() 
 and then iterate that collection calling yield return on it's items 
 but that seems like re doing something i already did.

提前谢谢.

推荐答案

您正在调用方法,但随后忽略了结果.您可能想要类似的东西:

You're calling the method, but then ignoring the results. You may want something like:

foreach (var item in childObject.Disassemble<T>())
{
    yield return item;
}

我认为您对yield return的功能有些困惑-它仅按当前执行的方法返回的顺序产生一个值 .它不会为某些全局序列添加值.如果您忽略递归Disassemble调用返回的值,则代码甚至不会执行执行,因为迭代器块是惰性的. (它们仅在要求另一个值时才执行代码.)

I think you're a bit confused about what yield return does - it only yields a value in the sequence returned by the currently-executing method. It doesn't add a value to some global sequence. If you ignore the value returned by the recursive Disassemble call, the code won't even execute as iterator blocks are lazy. (They only execute code when they're asked for another value.)

此外,方法末尾不需要yield break;.

Also, you don't need the yield break; at the end of your method.

请注意,如果递归进行得很深入,则使用迭代器块可能会导致效率低下.对您来说,这可能不成问题,但这是您需要考虑的问题.请参阅韦斯·代尔埃里克·利珀特关于这个.

Note that this if the recursion goes deep, this use of iterator blocks can be inefficient. That may well not be a problem for you, but it's something to think about. See posts by Wes Dyer and Eric Lippert about this.

这篇关于递归收益的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆