Click here to Skip to main content
15,881,898 members
Articles / Programming Languages / C#
Article

C# State machine - Yield

Rate me:
Please Sign up or sign in to vote.
1.50/5 (3 votes)
17 Jun 2012CPOL2 min read 24.3K   14   4
C# State machine - Yield

Introduction 

The yield keyword introduced in C# 2.0. The yield keyword allows you to create a state machine iterate through the collection of objects one by one.

Yield is a contextual keyword used in iterator methods in C#. Yield use like following in iterator block

C#
public IEnumerable methodname(params)
{
      foreach(type element in listofElement)
      {
         ...code for processing 
         yield return result;
      }
}

Note: Here IEnumerable can be replace by IEnumerable<T>.

So actually the yield keyword does is "When you process the collection by this keyword in iterator block. It pauses the execution and returns the proceeded element or the current element of the collection. And when you call it again it starts the execution with the next element which in turn becomes the current element for that call. This continues until it reachs the last element of the collection."

Now I am going to show how you how you can gain some performance when you make use of yield keyword.

In this example I am checking each datarow of the datatable weather it is empty or not.

Code With Yield Keyword

C#
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

C#
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 || (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

In Code (Code Without Yield Keyword)

In this code there is an extra list which gets created that points to the rows that match the condition. Then there is a loop for processing each row.

Disadvantage within this code is an extra list which gets created and occupies the extra space (i.e. occupies memory as well as slows down the code).

In Code (Code With Yield Keyword)

In this no extra list is getting created, with help yield one row at a time with a matching condition is getting processed. The advantage of the code is that there is no extra list getting created and also it also doesn't cause any performance problems.

The following is an example of LINQ with the yield keyword

C#
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 other statement besides yeild return

yield break stops returning sequence elements (this happens automatically if the control reaches the end of the iterator method body). The iterator code uses the yield return statement to return each element in turn. 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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India

Microsoft C# MVP (12-13)



Hey, I am Pranay Rana, working as a Team Leadin MNC. Web development in Asp.Net with C# and MS sql server are the experience tools that I have had for the past 5.5 years now.

For me def. of programming is : Programming is something that you do once and that get used by multiple for many years

You can visit my blog


StackOverFlow - http://stackoverflow.com/users/314488/pranay
My CV :- http://careers.stackoverflow.com/pranayamr

Awards:



Comments and Discussions

 
GeneralMy vote of 1 Pin
Daniel Cohen Gindi17-Nov-12 0:39
Daniel Cohen Gindi17-Nov-12 0:39 
Question[My vote of 2] State Machine? Pin
Keith Vinson19-Jun-12 4:02
Keith Vinson19-Jun-12 4:02 
GeneralMy vote of 3 Pin
jockey4her18-Jun-12 8:14
jockey4her18-Jun-12 8:14 
GeneralRe: My vote of 3 Pin
K.Ostrouska18-Jun-12 23:49
K.Ostrouska18-Jun-12 23:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.