DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Data Engineering
  3. AI/ML
  4. C# State Machine - Yield

C# State Machine - Yield

Pranay Rana user avatar by
Pranay Rana
·
Aug. 04, 12 · Interview
Like (0)
Save
Tweet
Share
6.27K Views

Join the DZone community and get the full member experience.

Join For Free
The 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.
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.

Popular on DZone

  • What Should You Know About Graph Database’s Scalability?
  • 9 Ways You Can Improve Security Posture
  • Learning by Doing: An HTTP API With Rust
  • 3 Ways That You Can Operate Record Beyond DTO [Video]

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: