Yield return 和异常处理
Yield return and exception handling
我刚刚遇到一个使用 yield return 的方法没有抛出我预期的 ArgumentException 的情况。我在这里用最简单的 类 重建了案例:
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 抛出异常?
这是因为 FooB
从未被计算过。
当您调用一个方法时,该方法会立即被调用。当您使用 yield
和 return 可枚举时,该方法仅在需要使用值 returned 时调用,并且一次只能调用一个项目;这就是 yield
ing 的好处。
因此,如果您添加使用值
的内容
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!");
}
您会看到预期的结果。
我刚刚遇到一个使用 yield return 的方法没有抛出我预期的 ArgumentException 的情况。我在这里用最简单的 类 重建了案例:
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 抛出异常?
这是因为 FooB
从未被计算过。
当您调用一个方法时,该方法会立即被调用。当您使用 yield
和 return 可枚举时,该方法仅在需要使用值 returned 时调用,并且一次只能调用一个项目;这就是 yield
ing 的好处。
因此,如果您添加使用值
的内容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!");
}
您会看到预期的结果。