65.9K
CodeProject 正在变化。 阅读更多。
Home

C# “Yield” 关键字的用途是什么?

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.84/5 (104投票s)

2013年4月10日

CPOL

3分钟阅读

viewsIcon

256022

在本博客中,我们将介绍 c# yield 关键字的 2 个重要用途。

“Yield 关键字帮助我们对 .NET 集合进行自定义有状态迭代。”
 
“yield”关键字在以下两种情况下很有用:-
 
 
  • 通过集合进行自定义迭代,而无需创建临时集合。
  • 有状态迭代。
 
 
场景 1:- 通过集合进行自定义迭代<o:p>
 

让我们通过一个例子来理解自定义迭代的含义。 考虑以下代码。

 
假设我们有一个名为“MyList”的简单列表,其中包含 5 个连续数值 1、2、3、4 和 5 的集合。 此列表从静态 void main 方法内的控制台应用程序浏览/迭代。
 

现在,让我们将“main()”方法可视化为调用者。 因此,调用者,即“main()”方法,调用列表并显示其中的项目。 就这么简单…直到现在 Wink | <img src= ".

static List<int> MyList = new List<int>();

static void FillValues()
{
            MyList.Add(1);
            MyList.Add(2);
            MyList.Add(3);
            MyList.Add(4);
            MyList.Add(5);
}
static void Main(string[] args) // Caller
{
            FillValues(); // Fills the list with 5 values
            foreach (int i in MyList) // Browses through the list
            {
                Console.WriteLine(i);
            }
            Console.ReadLine();
}
 
 
 
现在让我把情况复杂化,假设调用者只想要集合中大于“3”的值。 因此,作为 c# 开发人员,我们显而易见的事情是创建一个如下所示的函数。 这个函数将有一个临时集合。 在这个临时集合中,我们将首先添加大于“3”的值,并将相同的值返回给调用者。 然后,调用者可以迭代此集合。
static IEnumerable<int> FilterWithoutYield()

{
            List<int> temp = new List<int>();
            foreach (int i in MyList)
            {
                if (i > 3)
                {
                    temp.Add(i);
                }
            }
            return temp;
} 

 

 
 
 
 
 
现在上面的方法很好,但是如果我们能够摆脱集合,那将是很好的,这样我们的代码就会变得简单。 这就是“yield”关键字发挥作用的地方。 以下是一个简单的代码,说明了我们如何使用 yield。
 
“Yield”关键字会将控制权返回给调用者,调用者将完成他的工作并从他离开的地方重新进入该函数,并从该点开始继续迭代。 换句话说,“yield”关键字在调用者和集合之间来回移动程序的控制权。
static IEnumerable<int> FilterWithYield()

{
            foreach (int i in MyList)
            {
                if (i > 3) yield return i;
            }
}  
 
 

因此,对于上面的代码,以下是控制如何在调用者和集合之间流动的详细步骤。 您也可以在下面的下一个图中看到图形表示。

 
  • 步骤 1:- 调用者调用该函数以迭代大于 3 的数字。
  • 步骤 2:- 在函数内部,for 循环从 1 运行到 2,从 2 运行到 3,直到遇到大于“3”的值,即“4”。 只要满足大于 3 的值的条件,“yield”关键字就会将此数据发送回调用者。
  • 步骤 3:- 调用者在控制台上显示该值并重新进入该函数以获取更多数据。 这次当它重新进入时,它不会从头开始。 它会记住状态并从“5”开始。 迭代像往常一样继续。
 

 

 

 

 

 

 

 

场景 2:- 有状态迭代<o:p>

现在让我们给上面的场景增加更多的复杂性。 假设我们要显示上述集合的运行总计。 这是什么意思?

换句话说,我们将从 1 浏览到 5,并且在浏览时,我们将不断地将总计添加到变量中。 因此,我们从“1”开始,运行总计为“1”,我们移动到值“2”,运行总计为先前值“1”加上当前值“2”,即“3”,依此类推。

下面是运行总计的图形表示。

 


换句话说,我们希望迭代集合,并且在迭代时,我们希望保持运行总计状态并将该值返回给调用者(即控制台应用程序)。 所以现在的函数如下所示。“runningtotal”变量每次调用者重新进入该函数时都会有旧值。

 

 

static IEnumerable<int> RunningTotal()
         {
             int runningtotal=0;
             foreach(int i in MyList)
             {
                  runningtotal += i;
                 yield return (runningtotal);
                 
             }
         }
 
下面是调用者代码和输出。
foreach (int i in RunningTotal())

            {
                Console.WriteLine(i);
            } 
            Console.ReadLine(); 

<o:p>

 
 
 
 

关于使用 C# “Yield” 关键字的视频

进一步阅读,请观看下面的面试准备视频和分步视频系列。

© . All rights reserved.