1. There are two types of writing:
Yield return <expression> and yield break
Yield is used to return a value in an iteration and bring the value into the next iteration. Yield break means that iteration is stopped. In pure text descriptions, one thousand people have one thousand statements, which are more easily explained by code.
2. Official example (slightly modified ):
private void button1_Click(object sender, EventArgs e) { string s = string.Empty; foreach (int i in List.Power(2,8)) { s += i.ToString() + ","; } MessageBox.Show(s); } public class List { //using System.Collections; public static IEnumerable Power(int number, int exponent) { int counter = 0; int result = 1; while (counter++ < exponent) { result = result * number; yield return result; } } }
Run the example and find that the while code in the power method is executed once every cycle, that is, a value is output and brought into the next loop. The power function is not called every time.
For verification, we modify the official sample code to see if our judgment is correct:
private void button1_Click(object sender, EventArgs e) { string s = string.Empty; foreach (int i in List.Power()) { s += i.ToString() + ","; } MessageBox.Show(s); } public static IEnumerable Power() { int counter = 0; int result = 1; int number = 2, exponent = 8; while (counter++ < exponent) { result = result * number; yield return result; } }
The running result is the same as the official example, indicating that. NET Framework only performs iterative return processing for some codes of the yield part at a time.
3. Another official example is to use yield as an attribute (the output method is slightly modified ).
private void button2_Click(object sender, EventArgs e) { var theGalaxies = new Galaxies(); string ps = string.Empty; foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy) { ps += (theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString() + " >> "); } MessageBox.Show(ps); } public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy { get { yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 }; yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 }; yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 }; yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 }; } }
Output result:
From this example, we can see that yield is actually a temporary interrupted execution, and the execution will continue after the output.
You can modify this example to see how it works:
public class Galaxies { List<Galaxy> ls = new List<Galaxy>(); public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy { get { yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 }; yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 }; yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 }; yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 }; } } public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy1 { get { ls.Add(new Galaxy { Name = "Tadpole", MegaLightYears = 400 }); ls.Add(new Galaxy { Name = "Pinwheel", MegaLightYears = 25 }); ls.Add(new Galaxy { Name = "Milky Way", MegaLightYears = 0 }); ls.Add(new Galaxy { Name = "Andromeda", MegaLightYears = 3 }); int i = -1; while (i++ < ls.Count - 1) { yield return ls[i]; } } } }
After nextgalaxy1 is called, the results are the same as those in the official example. You can also modify nextgalaxy1 to make it easier to understand:
public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy1 { get { ls.Add(new Galaxy { Name = "Tadpole", MegaLightYears = 400 }); ls.Add(new Galaxy { Name = "Pinwheel", MegaLightYears = 25 }); ls.Add(new Galaxy { Name = "Milky Way", MegaLightYears = 0 }); ls.Add(new Galaxy { Name = "Andromeda", MegaLightYears = 3 }); int i = 0; while (i < ls.Count) { yield return ls[i]; i++; } } }
In this way, it is easy to understand its meaning. Furthermore, we can give you output results and continue to execute code for you!
If you want to interrupt the execution, use yield break directly.
The Code is as follows:
public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy1 { get { ls.Add(new Galaxy { Name = "Tadpole", MegaLightYears = 400 }); ls.Add(new Galaxy { Name = "Pinwheel", MegaLightYears = 25 }); ls.Add(new Galaxy { Name = "Milky Way", MegaLightYears = 0 }); ls.Add(new Galaxy { Name = "Andromeda", MegaLightYears = 3 }); int i = -1; while (i++ < ls.Count - 1) { yield return ls[i]; if (ls[i].MegaLightYears == 0) { yield break; } } } }
Output result:
Link: http://msdn.microsoft.com/zh-cn/library/9k7k7cf0.aspx