您的位置:首页 > 编程语言 > C#

【C#函数式编程】C#中的函数式编程(三) —— yield关键字的使用

2017-01-18 18:43 489 查看
        在C#和Python中都有yield关键字,在Python中通过使用yield关键字我们可以得到一个generator生成器,而在C#中使用yield关键字可以得到一个IEnumerable<T>类型的对象,可以理解成C#中的生成器。

        IEnumerable<T>对象是一种集合对象,比如List<T>对象、Dictionary<int,string>对象,可以用foreach进行遍历,而yield关键字的提出就是为了简化IEnumerable<T>类型的定义,它可以把函数做成一个IEnumerable<T>类型的对象。一般的诸如List<T>等对象,我们是在内存中构建了一系列元素的集合,使用foreach遍历时,需要访问每个元素的内存单元。而使用函数构建的IEnumerable<T>类型的对象,它只会占有一个元素的内存,foreach遍历时每次迭代都会执行函数中的代码,将结果存入这片内存,并同时记住本次迭代的位置。

        下面的例子,是MSDN上列举的一个使用yield的例子:

static void Main(string[] args)
{
foreach (var va in Power(2, 8, ""))
{
Console.WriteLine(va);
}
}

public static IEnumerable<int> Power(int number, intexponent, string s)
{
int result = 1;
for (int i = 0; i< exponent; i++)
{
result = result * number;
yieldreturn result;
}
yield return 3;
yield return 4;
yield return 5;
}
        Power函数的作用是计算number的exponent次方,我们通过使用关键字yield return将这个函数创建成了一个生成器,在主函数中用foreach遍历,每遍历一次就生成一个元素通过yield return 返回。



        每一次的迭代,都会执行上一次yield return之后的代码,并且到下一个yield return代码处为止。我们用下面的代码来验证这个问题:

public static IEnumerable<int> Print(intmin)
{
yield returnmin;
min += 1;
Console.WriteLine(string.Format("开a始º?第̨²2次ä?迭̨¹代䨲,ê?min={0}",min));

yield returnmin;
min += 1;
Console.WriteLine(string.Format("开a始º?第̨²3次ä?迭̨¹代䨲,ê?min={0}", min));

yield returnmin;
min += 1;
Console.WriteLine(string.Format("开a始º?第̨²4次ä?迭̨¹代䨲,ê?min={0}", min));

yield returnmin;
min += 1;
Console.WriteLine(string.Format("开a始º?第̨²5次ä?迭̨¹代䨲,ê?min={0}", min));

}
        在yield return之后,我们都会把参数min加1并打印到标准输出代表迭代次数的字符串:

第1次迭代,执行代码:

yield return min; 
第2次迭代,执行代码:

min += 1;
Console.WriteLine(string.Format("开a始º?第̨²2次ä?迭̨¹代䨲,ê?min={0}",min));
yield return min;
第3次迭代,执行代码:
min += 1;
Console.WriteLine(string.Format("开a始º?第̨²3次ä?迭̨¹代䨲,ê?min={0}",min));
yield return min;
……
        由于在第1次迭代时,yield
return min;之前没有任何代码,所以最后的打印结果应该会从第2次迭代开始打印,结果如下,验证了我们的结论。

 


 

Github位置:
https://github.com/HymanLiuTS/CSGroup
克隆本项目:
Git clone Git@github.com:HymanLiuTS/
CSGroup.git
获取本文源代码:
git checkout CSL04
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: