收益回报和异常处理 [英] Yield return and exception handling
问题描述
我刚刚遇到了一个使用yield return方法的情况,但没有抛出我期望的ArgumentException。我在这里用最简单的类重构了这种情况:
I just had a case with a method using yield return not throwing an ArgumentException which I expected. I have reconstructed the case with the simpliest possible classes here:
class Program
{
static void Main(string[] args)
{
try
{
var listA = FooA(count: 0);
Console.WriteLine("A did not throw exception!");
}
catch (ArgumentException)
{
Console.WriteLine("A threw exception!");
}
try
{
var listB = FooB(count: 0);
Console.WriteLine("B did not throw exception!");
}
catch (ArgumentException)
{
Console.WriteLine("B threw exception!");
}
Console.ReadLine();
}
private static IEnumerable<int> FooA(int count)
{
if(count == 0)
throw new ArgumentException("Count must be above 0");
var list = new List<int>();
for (var i = 0; i < count; i++)
{
list.Add(i);
}
return list;
}
private static IEnumerable<int> FooB(int count)
{
if (count == 0)
throw new ArgumentException("Count must be above 0");
for (var i = 0; i < count; i++)
{
yield return i;
}
}
}
输出:
A threw exception!
B did not throw exception!
有人可以向我解释为什么FooB在FooA不会抛出异常吗?
Can some one please explain to me why FooB does not throw an exception while FooA does?
推荐答案
这是因为 FooB
从未被评估过。
It's because FooB
is never even evaluated.
调用方法时,将立即调用该方法。当您使用 yield
并返回一个可枚举值时,仅当某些东西需要使用返回的值时才调用该方法,而一次只使用一个项。这就是 yield
ing的好处。
When you call a method, that method is called immediately. When you use yield
and return an enumerable, that method is only called when something needs to use the value returned, and only a single item at a time; this is the benefit of yield
ing.
因此,如果添加使用值的东西
So, if you add something that uses the value
try
{
var listB = FooB(count: 0);
Console.WriteLine(listB.First()); // use the IEnumerable returned
Console.WriteLine("B did not throw exception!");
}
catch (ArgumentException)
{
Console.WriteLine("B threw exception!");
}
您将看到预期的结果。
You will see your expected result.
这篇关于收益回报和异常处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!