本文发表在 rolia.net 枫下论坛有这么一段程序,要求写出打印结果
static void Main(string[] args)
{
try
{
var result = GetNames();
foreach (var s in result)
{
Console.WriteLine(s);
}
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
}
static IEnumerable<string> GetNames()
{
yield return "Wang";
yield return "Li";
yield return "Zhang";
throw new Exception("Bad Name");
}
打印结果是什么呢?大部分人(包括我)的第一感觉就是直接打印出“Bad Name”, 呵呵,其实结果是这个样子
Wang
Li
Zhang
System.Exception: Bad Name .....
为什么会这样?为什么不直接抛出异常呢?出这道题的考官很坏,这涉及到yield的特点,这个特点很多程序员很少注意
,那就是系统每次遇到一个yield,就会返回主调函数它后面的return值,等主调函数处理完毕之后再往下执行返回下一个yield return的值。也就是说
static IEnumerable<string> GetNames() 函数并不是首先生成里面所有可能的IEnumerable<string>,然后再返回这个IEnumerable<string>,而是动态的,一个一个返回,所以它发现不了最后面的那个throw exceptions
这个特点和LINQ的Lazy Operation很像,以后有时间说说LINQ的Lazy Operation更多精彩文章及讨论,请光临枫下论坛 rolia.net
static void Main(string[] args)
{
try
{
var result = GetNames();
foreach (var s in result)
{
Console.WriteLine(s);
}
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
}
static IEnumerable<string> GetNames()
{
yield return "Wang";
yield return "Li";
yield return "Zhang";
throw new Exception("Bad Name");
}
打印结果是什么呢?大部分人(包括我)的第一感觉就是直接打印出“Bad Name”, 呵呵,其实结果是这个样子
Wang
Li
Zhang
System.Exception: Bad Name .....
为什么会这样?为什么不直接抛出异常呢?出这道题的考官很坏,这涉及到yield的特点,这个特点很多程序员很少注意
,那就是系统每次遇到一个yield,就会返回主调函数它后面的return值,等主调函数处理完毕之后再往下执行返回下一个yield return的值。也就是说
static IEnumerable<string> GetNames() 函数并不是首先生成里面所有可能的IEnumerable<string>,然后再返回这个IEnumerable<string>,而是动态的,一个一个返回,所以它发现不了最后面的那个throw exceptions
这个特点和LINQ的Lazy Operation很像,以后有时间说说LINQ的Lazy Operation更多精彩文章及讨论,请光临枫下论坛 rolia.net