Author : Admin
Last Modified : 05-Sep-2020
Complexity : Beginner

yield keyword in C#


yield is a contextual keyword (for making it simple we will refer here only keyword). Developers generally confuse in the use of yield. But the yield keyword is very simple and straight forward. When we use the "yield" keyword in methods and get accessor, that method or get accessor works as an iterator. 

For understanding the use of yield keyword, first look below code without using yield keyword.

Example - Code is to print the "odd numbers" in a given range

using System;
using System.Collections.Generic;

namespace NonYieldExample
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (var num in GetOddNumber(1, 10))
            {
                Console.WriteLine("number is : {0}", num);
            }
            Console.ReadLine();
        }
        public static IEnumerable<int> GetOddNumber(int startNum, int endNumber)
        {
            List<int> oddNumList = new List<int>();
            for (int i = startNum; i <= endNumber; i++)
            {
                if (i % 2 != 0)
                {
                    oddNumList.Add(i);
                }
            }
            return oddNumList;
        }
    }
}

Output

number is : 1
number is : 3
number is : 5
number is : 7
number is : 9

We can see from the bold lines in above code, we need some temporary list to keep the match value so that code can finally return the result list, but Yield can remove the use of this holding collection.  We don't need to hold calculated value for return, we can return it as we got the value and come back and continue the loop. See the below example 

yield return keyword in Method

using System;
using System.Collections.Generic;

namespace YieldExample
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (var num in GetOddNumber(1, 10))
            {
                Console.WriteLine("number is : {0}", num);
            }
            Console.ReadLine();
        }
        public static IEnumerable<int> GetOddNumber(int startNum, int endNumber)
        {
            //List<int> oddNumList = new List<int>();
            for (int i = startNum; i <= endNumber; i++)
            {
                if (i % 2 != 0)
                {
                    //oddNumList.Add(i);
                    yield return i;
                }
            }
            //return oddNumList;
        }
    }
}

Output

number is : 1
number is : 3
number is : 5
number is : 7
number is : 9

So here in the above example, we are not storing the result, as the condition matches and found the odd number, it stops the loop and return to the calling statement which is GetOddNumber() for print and returns back to the loop.

Now we will see the use of Yield in get accessor.

yield return keyword in "get" accessor

using System;
using System.Collections.Generic;

namespace YieldExample
{
    class Program
    {
        static void Main(string[] args)
        {
            IEnumerable<int> numdata = GetOddNumber;
            foreach (var num in numdata)
            {
                Console.WriteLine("number is : {0}", num);
            }
            Console.ReadLine();
        }
        public static IEnumerable<int> GetOddNumber
        {
            get
            {
                yield return 1;
                yield return 3;
                yield return 5;
                yield return 7;
                yield return 9;
            }
        }
    }
}

Output

number is : 1
number is : 3
number is : 5
number is : 7
number is : 9

There are two forms of the yield statement

  • yield return <expression>
  • yield break

yield return <expression> - Already seen in above example, Use a yield return statement to return each element one at a time.

yield break - yield break statement is used to end the iteration.

"yield break" statement specific the end of the iteration.  when we are using "yield return" statement in any method or get accessor and want to break the iteration, we have to use "yield break". After "yield break" nothing will be executed and control return to the calling function.

yield break keyword in the method

Example

using System;
using System.Collections.Generic;

namespace YieldExample
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (var num in GetOddNumber(1, 10))
            {
                Console.WriteLine("number is : {0}", num);
            }
            Console.ReadLine();
        }
        public static IEnumerable<int> GetOddNumber(int startNum, int endNumber)
        {
            for (int i = startNum; i <= endNumber; i++)
            {
                if (i <= 4)
                {
                    yield return i;
                }
                else
                {
                    yield break;
                }
            }
        }
    }
}

Output

number is : 1
number is : 2
number is : 3
number is : 4

yield break keyword in get accessor

Example

using System;
using System.Collections.Generic;

namespace YieldExample
{
    class Program
    {
        static void Main(string[] args)
        {
            IEnumerable<int> numdata = GetOddNumber;
            foreach (var num in numdata)
            {
                Console.WriteLine("number is : {0}", num);
            }
            Console.ReadLine();
        }
        public static IEnumerable<int> GetOddNumber
        {
            get
            {
                yield return 1;
                yield return 3;
                yield return 5;
                yield break;
                yield return 7;
                yield return 9;
            }
        }
    }
}

Output

number is : 1
number is : 3
number is : 5