C# State Machine - Yield
Join the DZone community and get the full member experience.
Join For FreeThe Yield keyword was introduced in C#2.0. Yield allows the creation of a state machine and makes it iterate through the collection of objects one by one.
Yield is a contextual keyword used in iterator methods in C#. See yield being used in the following iterator block.
What yield the keyword does: "When you process the collection by this keyword in iterator block. It pause the execution return proceeded element or the current element of the collection. And when you call it again it start execution with the next element which in turn become current element for that call. This thing get continue till it reach the last element of collection."
Now I am going to show how you can gain some performance when you use yield.
In this example I am checking each datarow of the datatable whether it is empty or not.
Code With Yield Keyword
Code without yield keyword
In this code there is an extra list that gets created which points to the rows that are matching the condition and then there is a loop for processing each row.
Disadvantage With this code is an extra list that gets created which occupies the extra space i.e memory as well as slowing down the code.
Code with yield keyword
In this snippet there is no extra list that gets created. The matching conditions get processed one at a time.
Advantage There is no extra list that gets created and also it doesn't cause any performance problem.
Here's an example of LINQ with the yield keyword
yield break
This stops returning sequence elements (this happens automatically if control reaches the end of the iterator method body).
The iterator code uses the yield return statement to return each element in turn. A yield break ends the iteration.
Constraint
The yield statement can only appear inside an iterator block, which might be used as a body of a method, operator, or accessor. The body of such methods, operators, or accessors is controlled by the following restrictions:
Yield is a contextual keyword used in iterator methods in C#. See yield being used in the following iterator block.
public IEnumerable methodname(params) { foreach(type element in listofElement) { ...code for processing yield return result; } }Note : here IEnumerable can be replaced by IEnumerable<T>.
What yield the keyword does: "When you process the collection by this keyword in iterator block. It pause the execution return proceeded element or the current element of the collection. And when you call it again it start execution with the next element which in turn become current element for that call. This thing get continue till it reach the last element of collection."
Now I am going to show how you can gain some performance when you use yield.
In this example I am checking each datarow of the datatable whether it is empty or not.
Code With Yield Keyword
static void Main(string[] args) { int[] arr = new int[] { 1, 2, 3 }; DataTable table = new DataTable(); table.Columns.Add("ItemName", typeof(string)); table.Columns.Add("Quantity", typeof(int)); table.Columns.Add("Price", typeof(float)); table.Columns.Add("Process", typeof(string)); // // Here we add five DataRows. // table.Rows.Add("Indocin", 2, 23); table.Rows.Add("Enebrel", 1, 10); table.Rows.Add(null, null, null); table.Rows.Add("Hydralazine", 1, null); table.Rows.Add("Combivent", 3, 5); table.Rows.Add("Dilantin", 1, 6); foreach (DataRow dr in GetRowToProcess(table.Rows)) { if (dr != null) { dr["Process"] = "Processed"; Console.WriteLine(dr["ItemName"].ToString() + dr["Quantity"].ToString() + " : " + dr["Process"].ToString()); //bool test = dr.ItemArray.Any(c => c == DBNull.Value); } } Console.ReadLine(); } private static IEnumerable<datarow>GetRowToProcess(DataRowCollection dataRowCollection) { foreach (DataRow dr in dataRowCollection) { bool isempty = dr.ItemArray.All(x => x == null || (x!= null && string.IsNullOrWhiteSpace(x.ToString()))); if (!isempty) { yield return dr; //dr["Process"] = "Processed"; } else { yield return null; //dr["Process"] = " Not having data "; } //yield return dr; } }Code Without Yield Keyword
private static IList<datarow> GetRowToProcess(DataRowCollection dataRowCollection) { List<datarow> procedeedRows = new List<datarow><datarow>(); foreach (DataRow dr in dataRowCollection) { bool isempty = dr.ItemArray.All(x => x == null || </datarow> <datarow> (x!= null && string.IsNullOrWhiteSpace(x.ToString()))); if (!isempty) { procedeedRows.Add(dr); } } return procedeedRows; } static void Main(string[] args) { //code as above function to create datatable List<datarow> drs= GetRowToProcess(table.Rows); foreach (DataRow dr in drs) { //code to process the rows } } </datarow>Now Difference between two code
Code without yield keyword
In this code there is an extra list that gets created which points to the rows that are matching the condition and then there is a loop for processing each row.
Disadvantage With this code is an extra list that gets created which occupies the extra space i.e memory as well as slowing down the code.
Code with yield keyword
In this snippet there is no extra list that gets created. The matching conditions get processed one at a time.
Advantage There is no extra list that gets created and also it doesn't cause any performance problem.
Here's an example of LINQ with the yield keyword
void Main() { // This uses a custom 'Pair' extension method, defined below. List<string> list1 = new List<string>() { "Pranay", "Rana", "Hemang", "Vyas" }; IEnumerable<string><string> query = list1.Select (c => c.ToUpper()) .Pair() // Local from this point on. .OrderBy (n => n.length); } public static class MyExtensions { public static IEnumerable<string> Pair (this IEnumerable<string> source) { string firstHalf = null; foreach (string element in source) if (firstHalf == null) firstHalf = element; else { yield return firstHalf + ", " + element; firstHalf = null; } } } </string>There is another statement besides yield return
yield break
This stops returning sequence elements (this happens automatically if control reaches the end of the iterator method body).
The iterator code uses the yield return statement to return each element in turn. A yield break ends the iteration.
Constraint
The yield statement can only appear inside an iterator block, which might be used as a body of a method, operator, or accessor. The body of such methods, operators, or accessors is controlled by the following restrictions:
- Unsafe blocks are not allowed.
- Parameters to the method, operator, or accessor cannot be ref or out.
- A yield statement cannot appear in an anonymous method.
- When used with expression, a yield return statement cannot appear in a catch block or in a try block that has one or more catch clauses.
csharp
Machine
Published at DZone with permission of Pranay Rana, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
What Is JHipster?
-
Docker Compose vs. Kubernetes: The Top 4 Main Differences
-
Breaking Down the Monolith
-
What to Pay Attention to as Automation Upends the Developer Experience
Comments