我正在使用Visual Studio 2013。
执行以下代码时,ForEach2
输出到控制台,但ForEach
没有输出。我很惊讶我以为他们会有同样的结果。这是一个规范,还是我们的环境中出了问题?如果有的话,规格是什么?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var array = new[] { 1, 2, 3 };
Console.WriteLine("ForEach:");
array.ForEach(a => Console.WriteLine(a));
Console.WriteLine("ForEach2:");
array.ForEach2(a => Console.WriteLine(a));
Console.ReadKey();
}
}
static class Extension
{
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> target, Action<T> action)
{
foreach (var item in target)
{
action(item);
yield return item;
}
}
public static void ForEach2<T>(this IEnumerable<T> target, Action<T> action)
{
foreach (var item in target)
{
action(item);
}
}
}
}
当我设置断点时,它似乎一开始就没有进入ForEach
。我试图用[MethodImpl (MethodImplOptions.NoOptimization)]
抑制优化,但结果是一样的。
ForEach
方法中的yield
语句意味着在循环访问ForEach
返回的IEnumerable<T>
中的项之前不会执行该方法。通过在代码action(item);
行上放置断点,可以看到这是真的 - 不会命中断点。
如果您希望代码执行,则需要为从ForEach
返回的值添加一个foreach
。例如:
static void Main(string[] args)
{
var array = new[] { 1, 2, 3 };
Console.WriteLine("ForEach:");
array.ForEach(a => Console.WriteLine(a));
// add this line
foreach (var b in array.ForEach(a => Console.WriteLine(a))) { }
Console.WriteLine("ForEach2:");
array.ForEach2(a => Console.WriteLine(a));
Console.ReadKey();
}
新行将导致ForEach
执行并生成每个结果。这将导致action(item)
执行并将结果打印到控制台。
收益文档页面中的备注告诉您,您需要使用foreach
或LINQ
来使用yield
语句的结果。
你已定义生成器方法,但由于尚未枚举结果,因此没有任何反应。你想要哪个,回调还是枚举器?
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> target)
{
foreach (var item in target)
{
yield return item;
}
}
Console.WriteLine("ForEach:");
foreach (var item in array.ForEach())
Console.WriteLine(item);