期待したArgumentExceptionをスローしないyieldreturnを使用するメソッドのケースがありました。私はここで可能な限り単純なクラスでケースを再構築しました:
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!
FooAが例外をスローするのにFooBが例外をスローしない理由を誰かに説明してもらえますか?
それFooB
は決して評価されないからです。
メソッドを呼び出すと、そのメソッドがすぐに呼び出されます。yield
列挙可能オブジェクトを使用して返す場合、そのメソッドは、返された値を使用する必要がある場合にのみ呼び出され、一度に1つのアイテムのみが呼び出されます。これが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!");
}
期待どおりの結果が表示されます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加