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






4.84/5 (104投票s)
在本博客中,我们将介绍 c# yield 关键字的 2 个重要用途。
“Yield 关键字帮助我们对 .NET 集合进行自定义有状态迭代。”
“yield”关键字在以下两种情况下很有用:-
- 通过集合进行自定义迭代,而无需创建临时集合。
- 有状态迭代。
场景 1:- 通过集合进行自定义迭代<o:p>
让我们通过一个例子来理解自定义迭代的含义。 考虑以下代码。
假设我们有一个名为“MyList”的简单列表,其中包含 5 个连续数值 1、2、3、4 和 5 的集合。 此列表从静态 void main 方法内的控制台应用程序浏览/迭代。
现在,让我们将“main()”方法可视化为调用者。 因此,调用者,即“main()”方法,调用列表并显示其中的项目。 就这么简单…直到现在 ".
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” 关键字的视频
进一步阅读,请观看下面的面试准备视频和分步视频系列。