FakeLinq.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
class FakeLinq
{
public static IEnumerable<T> Where<T>(IEnumerable<T> source, Predicate<T> predicate) //source变量
{
if (source == null || predicate == null) //热情的检查参数
{
throw new ArgumentNullException();
}
return WhereImpl(source, predicate); //懒惰的处理数据 返回了Main() MoveNext就要调用 WhereImpl
}
private static IEnumerable<T> WhereImpl<T>(IEnumerable<T> source, Predicate<T> predicate)
{
foreach (T item in source) //调用ReadLines函数 返回上一个yield MoveNext返回到 ReadLines里面的foreach
{
if (predicate(item)) //检查当前项与谓词是否匹配 不匹配 就循环这个foreach, 这个foreach会用ReadLine的foreach
{//调用匿名方法 匹配 就返回 中断执行, 到下一个foreach,输出,返回到这个foreach
yield return item;
}
}//又开始循环
}
static void Main() //使用迭代器块实现LINQ的Where方法
{
IEnumerable<string> lines = LineReader.ReadLines("../../FakeLinq.cs"); // lines 和 predicate
Predicate<string> predicate = delegate(string line)
{ return line.StartsWith("using"); }; //要using 开头才会返回 才会匹配 item,才会执行下一个foreach输出
foreach (string line in Where(lines, predicate)) //调用Where 函数
{
Console.WriteLine(line);
}
}
}
LineReader.cs
class LineReader
{
public static IEnumerable<string> ReadLines(string filename)
{
using (TextReader reader = File.OpenText(filename))
{
string line;
while ((line = reader.ReadLine()) != null) //一般每次都会中断执行,得到line 每次中断执行,到WhereImpl的foreach
{//WhereImpl的foreach,会匹配 using, 匹配就
yield return line;
}
}
}
static void Main() //这个没用
{
foreach (string line in ReadLines("../../LineReader.cs"))
{
Console.WriteLine(line);
}
}
}
如果匹配就生成值,不匹配就测试下一项 直到找到匹配项或迭代完毕
谓词测试了某一行是否以"using"开头,当然包含更复杂的逻辑
输出
using System;
using System.Collections.Generic;
using System.ComponentModel;