Is yield useful outside of LINQ?

后端 未结 14 917
野性不改
野性不改 2020-12-24 06:44

When ever I think I can use the yield keyword, I take a step back and look at how it will impact my project. I always end up returning a collection instead of yeilding becau

14条回答
  •  無奈伤痛
    2020-12-24 07:26

    Yield is useful because it saves you space. Most optimizations in programming makes a trade off between space (disk, memory, networking) and processing. Yield as a programming construct allows you to iterate over a collection many times in sequence without needing a separate copy of the collection for each iteration.

    consider this example:

    static IEnumerable GetAllPeople()
    {
        return new List()
        {
            new Person() { Name = "George", Surname = "Bush", City = "Washington" },
            new Person() { Name = "Abraham", Surname = "Lincoln", City = "Washington" },
            new Person() { Name = "Joe", Surname = "Average", City = "New York" }
        };
    }
    
    static IEnumerable GetPeopleFrom(this IEnumerable people,  string where)
    {
        foreach (var person in people)
        {
            if (person.City == where) yield return person;
        }
        yield break;
    }
    
    static IEnumerable GetPeopleWithInitial(this IEnumerable people, string initial)
    {
        foreach (var person in people)
        {
            if (person.Name.StartsWith(initial)) yield return person;
        }
        yield break;
    }
    
    static void Main(string[] args)
    {
        var people = GetAllPeople();
        foreach (var p in people.GetPeopleFrom("Washington"))
        {
            // do something with washingtonites
        }
    
        foreach (var p in people.GetPeopleWithInitial("G"))
        {
            // do something with people with initial G
        }
    
        foreach (var p in people.GetPeopleWithInitial("P").GetPeopleFrom("New York"))
        {
            // etc
        }
    }
    

    (Obviously you are not required to use yield with extension methods, it just creates a powerful paradigm to think about data.)

    As you can see, if you have a lot of these "filter" methods (but it can be any kind of method that does some work on a list of people) you can chain many of them together without requiring extra storage space for each step. This is one way of raising the programming language (C#) up to express your solutions better.

    The first side-effect of yield is that it delays execution of the filtering logic until you actually require it. If you therefore create a variable of type IEnumerable<> (with yields) but never iterate through it, you never execute the logic or consume the space which is a powerful and free optimization.

    The other side-effect is that yield operates on the lowest common collection interface (IEnumerable<>) which enables the creation of library-like code with wide applicability.

提交回复
热议问题