I have seen the keyword "yield" n times, and I have not known the power of this keyword until recently. I will show some examples of using "yield" to make your code more readable and better performance.
To give you a quick overview of yield, I first want to show an example without this keyword. The following code is very simple, but it is very common in my recent projects.
IList<string> FindBobs(IEnumerable<string> names){var bobs = new List<string>();foreach(var currName in names){if(currName == "Bob")bobs.Add(currName);}return bobs;}
Note that here I use ienumerable <string> as the parameter type and use ilist <string> as the return type. Generally, I prefer the wider range of the parameter input type, the better, however, the return type is more strict (the translator presses: that is, base classes or interfaces are used for input, and subclass or implementation classes are used for return). For input, if you need to use foreach to loop it, it makes more sense to use ienumerable. For the output (the translator presses: that is, the return value), I use the interface to make the implementation part changeable. Here I want the caller to save the trouble of generating the list, so I select list as the return type.
The problem is that my design is not connectable. Such a design requires a list as the return value. In implementation, this list may not be very large, but this is not necessary.
Now, let's take a look at how to use yield, and then I will explain how it works.
IEnumerable<string> FindBobs(IEnumerable<string> names){foreach(var currName in names){if(currName == "Bob")yield return currName;}}
In this version, we changed the return type to ienumerable, and we used "yield return". Note that I no longer need to create a list. Is it confusing now? Don't worry. It will become simpler and easier to understand how it works.
When you use the "yield return" keyword group,. NET will generate a large string of Pipeline Code for you, although you can pretend that this is a magic. When a loop is started in the called Code (not a list here), the function is called once and again, however, each execution continues from the last execution exit.
Traditional execution methods
- Call a function
- Function execution and return list
- Call part to use the returned list
Yield execution Method
- Call a function
- The caller requests the item
- Next item return
- Back to step 2
Although the implementation of yield execution seems complicated, we only need to "Pop Up" an item at a time instead of creating the entire list and returning it.
For syntaxes, I personally think that yield is more concise and performs better for the purpose of passing functions ), I use ienumerable as the return type to notify the caller that it can be cyclically and return data,The caller can now decide on his or her ownWhether it is willing to store the returned values in the list, even if it is at the cost of performance.
In the simple example provided by me, you may not find many advantages of using yield. However, you can save a lot of unnecessary work when the caller needs to cancel traversing the content provided by all functions. When you use yield for method link, you can save the work (time) it may multiply.
Ayende has a great example: Using yield for a slick Pipes & filters implementation. He even talked about version that is multi-threaded. This makes me very interesting.
At first, I kept my opinion on yield that using this keyword may cause potential performance problems. However, so far, I have not found any information to illustrate the impact of yield on performance, the performance improvement I mentioned above is far greater than the overhead part of the compiler.
Summary
Yield can make your code more efficient and more readable. It is already in the. NET 2.0 era. I think there is no excuse to stop us from learning and using yield.