2

我正在尝试创建一个

    IEnumrable<PropertyInfo> 

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

请不要担心 INameValueWrapper 类型的内部包装对象

下面的问题是,当我遇到一个类属性时,我也不想在其上调用 Disassemble 并将其添加到 IEnumrable 的同一迭代中,当在我放置注释的地方调用它时,Dissasemble 不会再次发生: // 问题就在这里。

    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)为什么它没有被调用并添加到迭代中?

2)围绕这个问题的工作是什么?,

 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.

提前致谢。

4

2 回答 2

5

您正在调用该方法,但随后忽略了结果。你可能想要这样的东西:

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

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

此外,您不需要yield break;在方法结束时使用。

请注意,如果递归深入,则迭代器块的这种使用可能效率低下。这对你来说可能不是问题,但这是需要考虑的事情。请参阅Wes DyerEric Lippert的帖子。

于 2013-09-23T07:29:48.733 回答
3

代替

childObject.Dissasemble<T>(); // here is the problem 

尝试

foreach (var a in childObject.Dissasemble<T>())
{
 yield return a;
}
于 2013-09-23T07:31:51.003 回答