所以我有两种方法都通过IEnumerable
集合执行迭代。
public static IEnumerable<int> GetRange(int start, int count)
{
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count));
var end = start + count;
for (int value = start; value < end; value++)
{
yield return value;
}
}
public static IEnumerable<int> GetRangeFunction(int start, int count)
{
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count));
var end = start + count;
return RangeEnumeration();
//Using local function
IEnumerable<int> RangeEnumeration()
{
for (var value = start; value < end; value++)
{
yield return value;
}
}
}
我最近才知道返回IEnumerable
的方法直到被枚举才执行。
所以我创建了两个代码块来调用每个方法
调用GetRange
var iterator = GetRange(0, 10); // This does not start the execution of `GetRange` method. Instead, it waits till any item is requested
foreach(var item in iterator) //Now the GetRange method is called
{
}
GetRangeFunction
但是,在GetRangeFunction
的情况下,该方法会在创建迭代器时立即调用。
var iterator = GetRangeFunction(0, 5);
为什么这是行为?我还以为GetRangeFunction
直到请求一个项目才执行。
编辑
我的问题讲得不好,让我再解释一次。
两个枚举器都通过yield彼此返回项。但是对于 GetRange ,在对枚举数进行任何操作之前,不会执行任何语句(not even checking count is less than zero
)。但是,如果使用 GetRangeFunction ,则在调用该方法以创建迭代器时执行条件检查。
答案 0 :(得分:2)
根据MSDN,局部函数可以使异常立即浮出水面。例如,考虑以下代码。
static void Main()
{
IEnumerable<int> ienum = GetNumber(50, 110);
//below line will not execute if use GetNumberByLocalMethod
Console.WriteLine("Retrieved enumerator...");
foreach (var i in ienum)
{
Console.Write($"{i} ");
}
}
public static IEnumerable<int> GetNumberByLocalMethod(int start, int end)
{
throw new Exception("deliberately exception");
return InnerGetNumberByLocalMethod();
IEnumerable<int> InnerGetNumberByLocalMethod()
{
for (int i = start; i <= end; i++)
{
yield return i;
}
}
}
public static IEnumerable<int> GetNumber(int start, int end)
{
throw new Exception("deliberately exception");
for (int i = start; i <= end; i++)
{
yield return i;
}
}
为确保本地方法版本可以快速获取异常,GetNumberByLocalMethod版本将立即执行,而不必等到第一次迭代。