简体   繁体   中英

Nested IEnumerable<> in C#

I don't really need this feature, but an opportunity to simplify some code has presented itself if I could get the compiler to permit yield return with another IEnumerable<> . Example shown below:

static void Main(string[] args){
    foreach (string str in EnumerateA())
        Console.WriteLine(str);
}
static IEnumerable<string> EnumerateA(){
    yield return "1";
    yield return EnumerateB("2");
    yield return EnumerateB("3");
}
static IEnumerable<string> EnumerateB(string num){
    yield return num + "+";
    yield return num + "-";
}

I know that I can replace

yield return EnumerateB("2")

with

foreach(string str in EnumerateB("2")) yield return str;

and have that work, but is that the only way this would work? I'm targeting .NET 2.0 .

Yes, that is the only way it would work. Each value should be returned using the 'yield return', you cannot return values as group of collection.

This is wrong

static IEnumerable<string> EnumerateA()
{
    yield return "1";
    yield return EnumerateB("2");
    yield return EnumerateB("3");
}

Correct way would be

static IEnumerable<string> EnumerateA()
{
    yield return "1";
    foreach (var str in EnumerateB("2"))
    {
        yield return str;
    }
    foreach (var str in EnumerateB("3"))
    {
        yield return str;
    }
}

As a fairly simple alternative you could implement your code using normal static methods.

Just define these:

public static class Enumerable
{
    public static IEnumerable<T> Return<T>(T value)
    {
        yield return value;
    }

    public static IEnumerable<T> Concat<T>(params IEnumerable<T>[] lists)
    {
        foreach (var values in lists)
            foreach (var value in values)
                yield return value;
    }
}

Then implement your method like this:

static IEnumerable<string> EnumerateA()
{
    return
        Enumerable.Concat(
            Enumerable.Return("1"),
            EnumerateB("2"),
            EnumerateB("3"));
}

I know it is not as nice as using static methods that given a good fluent architecture, but it's not too bad I think. It will also help if, in the future, you get to upgrade your code. If you follow the linq signatures the code may even still run with few changes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM