<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_my diary</title><subtitle type="text">of reading and learning</subtitle><id>http://feed.cnblogs.com/blog/u/41661/rss</id><updated>2012-04-10T03:57:34Z</updated><author><name>崔鹏飞</name><uri>http://www.cnblogs.com/cuipengfei/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cuipengfei/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/41661/rss"/><entry><id>http://www.cnblogs.com/cuipengfei/archive/2012/04/09/2438764.html</id><title type="text">自己动手重新实现LINQ to Objects: 11 - First，Last，Single以及它们带有OrDefault的重载</title><summary type="text">本文翻译自JonSkeet的系列博文“Edulinq”。本篇原文地址：http://msmvps.com/blogs/jon_skeet/archive/2010/12/29/reimplementing-linq-to-objects-part-11-first-single-last-and-the-ordefault-versions.aspx今天我实现了六个操作符，每个操作符都有两个重载。我一开始以为这些操作符的实现会很相似，但是最后发现每个都稍微有些不同...今天实现了哪些操作符？以下三个集合的排列{First,Last,Single},{带有/不带有OrDefault},{带有/不</summary><published>2012-04-09T04:54:00Z</published><updated>2012-04-09T04:54:00Z</updated><author><name>崔鹏飞</name><uri>http://www.cnblogs.com/cuipengfei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cuipengfei/archive/2012/04/09/2438764.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cuipengfei/archive/2012/04/09/2438764.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0"&gt;本文翻译自&lt;a href="http://stackoverflow.com/users/22656/jon-skeet"&gt;Jon&amp;nbsp;Skeet&lt;/a&gt;的系列博文&amp;ldquo;&lt;span style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;&amp;rdquo;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;本篇原文地址：&lt;/p&gt;&lt;p class="p0"&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2010/12/29/reimplementing-linq-to-objects-part-11-first-single-last-and-the-ordefault-versions.aspx"&gt;http://msmvps.com/blogs/jon_skeet/archive/2010/12/29/reimplementing-linq-to-objects-part-11-first-single-last-and-the-ordefault-versions.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;今天我实现了六个操作符，每个操作符都有两个重载。我一开始以为这些操作符的实现会很相似，但是最后发现每个都稍微有些不同...&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;今天实现了哪些操作符？&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;以下三个集合的排列&lt;span style="font-family: 'Times New Roman';"&gt;{First,&amp;nbsp;Last,&amp;nbsp;Single},&amp;nbsp;{&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;带有&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;/&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;不带有&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;OrDefault&amp;nbsp;},&amp;nbsp;{&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;带有&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;/&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;不带有谓词&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;}&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;，其结果是十二个不同的方法签名：&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource First&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource First&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source, &lt;br/&gt;    Func&lt;/span&gt;&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt; predicate) &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource FirstOrDefault&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource FirstOrDefault&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source, &lt;br/&gt;    Func&lt;/span&gt;&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt; predicate) &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource Last&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource Last&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source, &lt;br/&gt;    Func&lt;/span&gt;&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt; predicate) &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource LastOrDefault&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource LastOrDefault&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source, &lt;br/&gt;    Func&lt;/span&gt;&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt; predicate) &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource Single&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource Single&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source, &lt;br/&gt;    Func&lt;/span&gt;&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt; predicate) &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource SingleOrDefault&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource SingleOrDefault&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source, &lt;br/&gt;    Func&lt;/span&gt;&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt; predicate)&lt;/div&gt;&lt;p class="p0"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="p0"&gt;这些操作符有以下的共同点：&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;它们都是接受一个泛型参数的扩展方法&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;它们都是立即执行的&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;他们都会检查参数是否为&lt;span style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;这些操作符的接受谓词的重载和以下形式等价：source.Where(谓词).该操作符()。换句话说，这些接受谓词的重载就是在执行操作符之前过滤一下&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;了解了上面这几点之后，对于每个操作符就只需考虑三种可能性：在谓词执行之后（如果有谓词的话），如果源序列是空的怎么处理？源序列只包含一个元素怎么处理？如果源序列包含多个元素如何处理？我们可以用一个简单的表来描述上述问题的结果：&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="center" width="116"&gt;&lt;p class="p0"&gt;操作符&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="142"&gt;&lt;p class="p0"&gt;如果源序列是空的&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="159"&gt;&lt;p class="p0"&gt;源序列只包含一个元素&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="144"&gt;&lt;p class="p0"&gt;源序列包含多个元素&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="center" width="116"&gt;&lt;p class="p0"&gt;First&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="142"&gt;&lt;p class="p0"&gt;抛异常&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="159"&gt;&lt;p class="p0"&gt;返回该元素&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="144"&gt;&lt;p class="p0"&gt;返回第一个元素&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="center" width="116"&gt;&lt;p class="p0"&gt;FirstOrDefault&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="142"&gt;&lt;p class="p0"&gt;返回default(TSource)&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="159"&gt;&lt;p class="p0"&gt;返回该元素&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="144"&gt;&lt;p class="p0"&gt;返回第一个元素&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="center" width="116"&gt;&lt;p class="p0"&gt;Last&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="142"&gt;&lt;p class="p0"&gt;抛异常&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="159"&gt;&lt;p class="p0"&gt;返回该元素&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="144"&gt;&lt;p class="p0"&gt;返回最后一个元素&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="center" width="116"&gt;&lt;p class="p0"&gt;LastOrDefault&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="142"&gt;&lt;p class="p0"&gt;返回default(TSource)&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="159"&gt;&lt;p class="p0"&gt;返回该元素&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="144"&gt;&lt;p class="p0"&gt;返回最后一个元素&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="center" width="116"&gt;&lt;p class="p0"&gt;Single&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="142"&gt;&lt;p class="p0"&gt;抛异常&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="159"&gt;&lt;p class="p0"&gt;返回该元素&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="144"&gt;&lt;p class="p0"&gt;抛异常&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="center" width="116"&gt;&lt;p class="p0"&gt;SingleOrDefault&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="142"&gt;&lt;p class="p0"&gt;返回default(TSource)&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="159"&gt;&lt;p class="p0"&gt;返回该元素&lt;/p&gt;&lt;/td&gt;&lt;td valign="center" width="144"&gt;&lt;p class="p0"&gt;抛异常&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;很明显，如果输入序列只有一个元素的话，这几个操作符的执行结果是非常一致的:)&amp;nbsp;类似的，如果输入的序列是空的的话，那么没有&amp;ldquo;&lt;span style="font-family: 'Times New Roman';"&gt;OrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;&amp;rdquo;的操作符会抛异常（&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;InvalidOperationException&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;），而带有&amp;ldquo;&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;OrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;&amp;rdquo;的操作符则会返回元素类型的默认值（引用类型的默认值为&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;，&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;int&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的默认值为&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;0&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;，等等）。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;如果（可能是被过滤过的）输入序列含有多个元素的话，那这些操作符的执行结果的差异是很大的，First和&lt;span style="font-family: 'Times New Roman';"&gt;Last&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的结果是顾名思义的，而&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Single&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;抛出异常。值得注意的是，&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;SingleOrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;也会抛出异常，因为它要做的事又不是像这样：如果输入序列只有一个元素的话，返回该元素，否则的话返回默认值。如果你需要能够处理多元素序列的操作符的话，用&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;First&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;或&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Last&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;。如果你需要处理可能为空的序列的话，使用&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;FirstOrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;或&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;LastOrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;。请注意，如果使用带有&amp;ldquo;&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;OrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;&amp;rdquo;的操作符的话，那么一个空的序列和一个仅包含默认值的序列的执行结果会是完全一样的。我们稍后会提到&lt;/span&gt;DefaultIfEmpty。&lt;/p&gt;&lt;p class="p0"&gt;现在我们知道这些操作符做什么了，我们来开始测试吧。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;我们要测试什么？&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;今天早晨，我发了一条推文说我在开始实现之前就写了&lt;span style="font-family: 'Times New Roman';"&gt;72&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;个测试用例。实际上，我最终写了&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;80&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;个，为什么写了&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;80&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;我们稍后会说。对每一个操作符，我测试了&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;12&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;个用例：&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;源序列是否为&lt;span style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的测试（没有谓词的重载）&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;源序列是否为&lt;span style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的测试（有谓词的重载）&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;谓词是否为&lt;span style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的测试&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;源序列不包含元素的测试（没有谓词的重载）&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;源序列不包含元素的测试（有谓词的重载）&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;源序列只包含一个元素的测试（没有谓词的重载）&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;源序列只包含一个元素，且该元素符合谓词的测试&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;源序列只包含一个元素，且该元素不符合谓词的测试&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;源序列包含多个元素的测试（没有谓词的重载）&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;源序列包含多个元素且只有一个元素符合谓词的测试&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;源序列包含多个元素且多个元素符合谓词的测试&lt;/p&gt;&lt;p class="p0"&gt;实现这些测试用例时，我做了很多复制粘贴，每个操作符的测试用例用的都是同一组数据，只是预期的结果值不同。&lt;/p&gt;&lt;p class="p0"&gt;另外，First和&lt;span style="font-family: 'Times New Roman';"&gt;FirstOrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;分别有两个额外的测试，&lt;/span&gt;Last和LastOrDefault也分别有两个：&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;First和FirstOrDefault：当没有谓词的时候，这两个方法应该在遇到第一个元素时就立刻返回，不应该继续遍历序列的剩余部分&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;First&lt;span style="font-family: SimSun;"&gt;和&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;FirstOrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;：当有谓词的时候，应该在找到第一个符合谓词的元素时就立刻返回&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;Last和&lt;span style="font-family: 'Times New Roman';"&gt;LastOrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;：当源序列实现了&lt;/span&gt;IList&amp;lt;T&amp;gt;且没有谓词时，这两个方法使用源序列的&lt;span style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;属性和索引器去访问最后一个元素，这是一个特殊优化&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;Last和LastOrDefault：当源序列实现了&lt;span style="font-family: 'Times New Roman';"&gt;IList&lt;/span&gt;&amp;lt;T&amp;gt;且有谓词的时候，则没有上述的优化。这种情况下，这两个方法要彻底遍历整个源序列&lt;/p&gt;&lt;p class="p0"&gt;上面提到的后两个测试用到了一个叫做&lt;span style="font-family: 'Times New Roman';"&gt;NonEnumerableList&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的新集合类型，这个类型的所有方法实现都依赖于一个&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;List&lt;/span&gt;&amp;lt;T&amp;gt;，除了&lt;span style="font-family: 'Times New Roman';"&gt;GetEnumerator&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;方法（泛型的和非泛型的）之外，这两个方法仅仅是抛出&lt;/span&gt;NotSupportedException异常。这一点对于测试上述的优化很有帮助，有关优化的问题我们说到的时候再谈。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;来动手实现吧！&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;这几个操作符的实现比我预期的要有趣，所以我下面要把十二个方法实现都列出来。这些方法可不是复制粘贴一下了事的，参数验证的部分除外。&lt;/p&gt;&lt;p class="p0"&gt;如果我们基于&lt;span style="font-family: 'Times New Roman';"&gt;Where&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;和没有谓词的重载来实现有谓词的重载，并且基于&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;DefaultIfEmpty&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;和名字中不含&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Default&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的重载来实现名字中含有&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Default&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的重载的话，那么我们就只需要实现三个没有谓词和名字里没有&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Default&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的方法。但是，就像我之前说过的那样，单独的实现每个操作符会有一些好处。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;为了避免看起来冗余，我把每个方法中的参数检验的部分省略掉了。不过在真实的代码中是含有参数检验的。我们从&lt;span style="font-family: 'Times New Roman';"&gt;First&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;开始吧：&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource First&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;{ &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Argument validation elided &lt;/span&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (IEnumerator&amp;lt;TSource&amp;gt; iterator =&lt;span style="color: #000000;"&gt; source.GetEnumerator()) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (iterator.MoveNext()) &lt;br/&gt;        { &lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; iterator.Current; &lt;br/&gt;        } &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Sequence was empty&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br/&gt;    } &lt;br/&gt;} &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource First&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source, &lt;br/&gt;    Func&lt;/span&gt;&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt; predicate) &lt;br/&gt;{ &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Argument validation elided &lt;/span&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (TSource item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (predicate(item)) &lt;br/&gt;        { &lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; item; &lt;br/&gt;        } &lt;br/&gt;    } &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;No items matched the predicate&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br/&gt;}&lt;/span&gt;&lt;/div&gt;&lt;p class="p0"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="p0"&gt;这两个实现看起来差异很大，这是我有意为之的。对于没有谓词的重载，我也可以用&lt;span style="font-family: 'Times New Roman';"&gt;foreach&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;来实现的，就从&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;foreach&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的循环体中无条件的返回就可以了。然而，我想要强调我们在&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;First&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;中不需要循环遍历。我们只需要移向第一个元素，然后返回就可以了，如果无法移向第一个元素则抛出异常。没有任何迹象显示我们会再次调用&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;MoveNext&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;。而对于有谓词的重载，我们必须一直循环遍历直到找到一个符合谓词的元素，我们只在遍历完所有元素而找不到符合谓词的元素时才抛出异常。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;下面我们来看看当序列为空时如何返回默认值：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource FirstOrDefault&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;{ &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Argument validation elided &lt;/span&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (IEnumerator&amp;lt;TSource&amp;gt; iterator =&lt;span style="color: #000000;"&gt; source.GetEnumerator()) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; iterator.MoveNext() ? iterator.Current : &lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;(TSource); &lt;br/&gt;    } &lt;br/&gt;} &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource FirstOrDefault&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source, &lt;br/&gt;    Func&lt;/span&gt;&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt; predicate) &lt;br/&gt;{ &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Argument validation elided &lt;/span&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (TSource item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (predicate(item)) &lt;br/&gt;        { &lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; item; &lt;br/&gt;        } &lt;br/&gt;    } &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;(TSource); &lt;br/&gt;}&lt;/span&gt;&lt;/div&gt;&lt;p class="p0"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="p0"&gt;这个有谓词的&lt;span style="font-family: 'Times New Roman';"&gt;FirstOrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;看起来和有谓词的&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;First&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;非常相似，但是没有谓词的&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;FirstOrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;和没有谓词的&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;First&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;却有点细微的差别：我们在这里没有用&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;if&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;语句而是用了三元运算符（虽然说用&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;if&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;也是完全可以的）。不管能否移向第一个元素，我们都需要返回值。如果三元运算符允许第二个或第三个操作对象为&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;throw&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;语句就好了，但是即使不能的话也不是什么大问题。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;接下来我们来实现&lt;span style="font-family: 'Times New Roman';"&gt;Single&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;，它在某些方面与&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;First&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的相似性比&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Last&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;与&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;First&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的相似性更大：&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource Single&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;{ &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Argument validation elided &lt;/span&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (IEnumerator&amp;lt;TSource&amp;gt; iterator =&lt;span style="color: #000000;"&gt; source.GetEnumerator()) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color: #000000;"&gt;iterator.MoveNext()) &lt;br/&gt;        { &lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Sequence was empty&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br/&gt;        } &lt;br/&gt;        TSource ret &lt;/span&gt;=&lt;span style="color: #000000;"&gt; iterator.Current; &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (iterator.MoveNext()) &lt;br/&gt;        { &lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Sequence contained multiple elements&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br/&gt;        } &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; ret; &lt;br/&gt;    } &lt;br/&gt;} &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource Single&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source, &lt;br/&gt;    Func&lt;/span&gt;&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt; predicate) &lt;br/&gt;{ &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Argument validation elided &lt;/span&gt;&lt;br/&gt;    TSource ret = &lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;(TSource); &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; foundAny = &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (TSource item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (predicate(item)) &lt;br/&gt;        { &lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (foundAny) &lt;br/&gt;            { &lt;br/&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Sequence contained multiple matching elements&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br/&gt;            } &lt;br/&gt;            foundAny &lt;/span&gt;= &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;br/&gt;            ret &lt;/span&gt;=&lt;span style="color: #000000;"&gt; item; &lt;br/&gt;        } &lt;br/&gt;    } &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color: #000000;"&gt;foundAny) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;No items matched the predicate&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br/&gt;    } &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; ret; &lt;br/&gt;}&lt;/span&gt;&lt;/div&gt;&lt;p class="p0"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="p0"&gt;这个比&lt;span style="font-family: 'Times New Roman';"&gt;First&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;复杂多了。没有谓词的重载的开头和&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;First&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的开头一样，不同的是如果能够成功的移向第一个元素的话，我们需要记住第一个元素的值（因为我们可能需要返回该值）然后试着移向第二个元素。如果可以移向第二个元素，就要抛出异常，如果不能移向第二个元素，那就可以返回刚才记录下的值。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;有谓词的重载更麻烦。我们依然需要记住第一个找到的符合谓词的值，不过因为这次我们在循环，我们还需要记住是否已经找到过一个符合谓词的值了。如果能够找到第二个符合谓词的值，就必须抛异常。如果一个符合谓词的值都找不到，也要抛异常。请注意，尽管我们给&lt;span style="font-family: 'Times New Roman';"&gt;ret&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;赋了一个&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;default&lt;/span&gt;(TSource)的初值，但是我们的&lt;span style="font-family: 'Times New Roman';"&gt;return&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;语句执行时&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;ret&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;肯定不会是初值的状态。然而，&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;C#&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的明确赋值的语法无法理解这一点，所以我们需要给&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;ret&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;一个&amp;ldquo;傀儡&amp;rdquo;式的初值，而&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;default&lt;/span&gt;(T)是唯一可以用的值。有另外一种不用&lt;span style="font-family: 'Times New Roman';"&gt;foreach&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的实现方法：遍历序列直到找到第一个符合谓词的元素，此时声明一个局部变量并且把找到的元素赋值给该变量，然后再开始另一个循环，以确保不能再找到其他符合谓词的值了。我个人觉得这种方式太复杂了，所以我选择了用&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;foreach&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的方式。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;下面实现&lt;span style="font-family: 'Times New Roman';"&gt;SingleOrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的两个重载，这两个重载之间的差别就不是那么大了：&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource SingleOrDefault&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;{ &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Argument validation elided &lt;/span&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (IEnumerator&amp;lt;TSource&amp;gt; iterator =&lt;span style="color: #000000;"&gt; source.GetEnumerator()) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color: #000000;"&gt;iterator.MoveNext()) &lt;br/&gt;        { &lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;(TSource); &lt;br/&gt;        } &lt;br/&gt;        TSource ret &lt;/span&gt;=&lt;span style="color: #000000;"&gt; iterator.Current; &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (iterator.MoveNext()) &lt;br/&gt;        { &lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Sequence contained multiple elements&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br/&gt;        } &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; ret; &lt;br/&gt;    } &lt;br/&gt;} &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource SingleOrDefault&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source, &lt;br/&gt;    Func&lt;/span&gt;&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt; predicate) &lt;br/&gt;{ &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Argument validation elided &lt;/span&gt;&lt;br/&gt;    TSource ret = &lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;(TSource); &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; foundAny = &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (TSource item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (predicate(item)) &lt;br/&gt;        { &lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (foundAny) &lt;br/&gt;            { &lt;br/&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Sequence contained multiple matching elements&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br/&gt;            } &lt;br/&gt;            foundAny &lt;/span&gt;= &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;br/&gt;            ret &lt;/span&gt;=&lt;span style="color: #000000;"&gt; item; &lt;br/&gt;        } &lt;br/&gt;    } &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; ret; &lt;br/&gt;}&lt;/span&gt;&lt;/div&gt;&lt;p class="p0"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="p0"&gt;这次我们只是把没有谓词的重载里的&lt;span style="font-family: 'Times New Roman';"&gt;throw&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;语句替换成了&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;return&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;语句，并且在有谓词的重载中移除了没有找到符合谓词的元素的判断。我们在这里给&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;ret&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;赋以初值是有好处的，因为如果后面的代码不会给&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;ret&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;赋以其他值，那么&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;ret&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;已经有了正确的返回值了。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;下一个是&lt;span style="font-family: 'Times New Roman';"&gt;Last&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;：&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource Last&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;{ &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Argument validation elided &lt;/span&gt;&lt;br/&gt;    IList&amp;lt;TSource&amp;gt; list = source &lt;span style="color: #0000ff;"&gt;as&lt;/span&gt; IList&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;; &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (list != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (list.Count == &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br/&gt;        { &lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Sequence was empty&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br/&gt;        } &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; list[list.Count - &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]; &lt;br/&gt;    } &lt;br/&gt;&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (IEnumerator&amp;lt;TSource&amp;gt; iterator =&lt;span style="color: #000000;"&gt; source.GetEnumerator()) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color: #000000;"&gt;iterator.MoveNext()) &lt;br/&gt;        { &lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Sequence was empty&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br/&gt;        } &lt;br/&gt;        TSource last &lt;/span&gt;=&lt;span style="color: #000000;"&gt; iterator.Current; &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; (iterator.MoveNext()) &lt;br/&gt;        { &lt;br/&gt;            last &lt;/span&gt;=&lt;span style="color: #000000;"&gt; iterator.Current; &lt;br/&gt;        } &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; last; &lt;br/&gt;    } &lt;br/&gt;} &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource Last&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source, &lt;br/&gt;    Func&lt;/span&gt;&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt; predicate) &lt;br/&gt;{ &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Argument validation elided &lt;/span&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; foundAny = &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;br/&gt;    TSource last &lt;/span&gt;= &lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;(TSource); &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (TSource item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (predicate(item)) &lt;br/&gt;        { &lt;br/&gt;            foundAny &lt;/span&gt;= &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;br/&gt;            last &lt;/span&gt;=&lt;span style="color: #000000;"&gt; item; &lt;br/&gt;        } &lt;br/&gt;    } &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color: #000000;"&gt;foundAny) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;No items matched the predicate&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br/&gt;    } &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; last; &lt;br/&gt;}&lt;/span&gt;&lt;/div&gt;&lt;p class="p0"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="p0"&gt;我们从没有谓词的方法开头的优化谈起吧。如果输入序列是个列表的话，我们可以获取列表的元素数量，然后根据元素数量的不同，或者是抛出异常或者是返回索引最大的元素。如果还要再优化一点的话，我可以把&lt;span style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;值存到一个局部变量里，但是我假设获取&lt;/span&gt;IList&amp;lt;T&amp;gt;的&lt;span style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的代价是很低的。如果有哪位对这一点持反对意见，我很愿意做出修改：）请注意，我还假设了另一个情况，实现&lt;/span&gt;IList&amp;lt;T&amp;gt;的类型含有的元素不会超过Int32.MaxValue，否则的话，这个优化就会失败。&lt;/p&gt;&lt;p class="p0"&gt;如果不做优化的话，我们可以遍历整个序列，每次迭代都用最新访问到的元素来更新一个局部变量的值。我在这里没有用&lt;span style="font-family: 'Times New Roman';"&gt;foreach&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;，但是并没有什么特别的原因&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;--&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;我们其实也可以用&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;foreach&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;，每次的迭代都把一个叫做&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;foundAny&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的变量设为&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;true&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;，然后在最后测试&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;foundAny&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;的值。实际上，上面所描述的就正是有谓词的方法所采用的方式。不许得承认，采用这个方式在一定程度上是不得已而为之&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;--&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;我们不能调用&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;MoveNext&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;然后把获取到的值存起来，因为这个值有可能不符合谓词的约束。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;Last&lt;span style="font-family: SimSun;"&gt;的有谓词的重载没有优化，这是&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;LINQ&amp;nbsp;to&amp;nbsp;Objects&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;（官方实现）的做法，但是我不知道这么做的原因。我们可以利用索引器来从后向前反向遍历。有一个可能的解释是：谓词在处理某些值时有可能会抛出异常，如果我们在处理实现了&lt;/span&gt;IList&amp;lt;T&amp;gt;的序列的时候直接跳到序列尾部的话，就会造成可观察的差别。我很想知道这是不是真的原因&lt;span style="font-family: 'Times New Roman';"&gt;--&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;如果哪位能够提供内部信息的话，我会更新这篇博文。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;现在，我们就只有一个操作符需要实现了&lt;span style="font-family: 'Times New Roman';"&gt;--LastOrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;：&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource LastOrDefault&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;{ &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Argument validation elided &lt;/span&gt;&lt;br/&gt;    IList&amp;lt;TSource&amp;gt; list = source &lt;span style="color: #0000ff;"&gt;as&lt;/span&gt; IList&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;; &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (list != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; list.Count == &lt;span style="color: #800080;"&gt;0&lt;/span&gt; ? &lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;(TSource) : list[list.Count - &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]; &lt;br/&gt;    } &lt;br/&gt;&lt;br/&gt;    TSource last &lt;/span&gt;= &lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;(TSource); &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (TSource item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;    { &lt;br/&gt;        last &lt;/span&gt;=&lt;span style="color: #000000;"&gt; item; &lt;br/&gt;    } &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; last; &lt;br/&gt;} &lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; TSource LastOrDefault&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt;( &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt;&lt;span style="color: #000000;"&gt; source, &lt;br/&gt;    Func&lt;/span&gt;&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt; predicate) &lt;br/&gt;{ &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Argument validation elided &lt;/span&gt;&lt;br/&gt;    TSource last = &lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;(TSource); &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (TSource item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; source) &lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (predicate(item)) &lt;br/&gt;        { &lt;br/&gt;            last &lt;/span&gt;=&lt;span style="color: #000000;"&gt; item; &lt;br/&gt;        } &lt;br/&gt;    } &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; last; &lt;br/&gt;}&lt;/span&gt;&lt;/div&gt;&lt;p class="p0"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="p0"&gt;除了优化的部分，有谓词的和没有谓词的方法看起来很相似...比其他操作符的两个重载之间的差异要小。两个重载中，我们都是先定义一个返回值，并赋值为&lt;span style="font-family: 'Times New Roman';"&gt;default&lt;/span&gt;(TSource)，然后遍历整个序列，并更新返回值，如果有谓词的话，就仅当元素符合谓词时才更新返回值。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;结论&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;我今早起床时没料到这篇博文会写的这么长，不过我希望上述的各个实现之间的差异和"Last/LastOrDefault"没有优化的怪事能够值得这么多的辛苦。&lt;/p&gt;&lt;p class="p0"&gt;虽然前面提到了&lt;span style="font-family: 'Times New Roman';"&gt;DefaultIfEmpty&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;，但是我准备下次再实现它。虽然说如果今晚抓紧的话，还是可以做完的&lt;/span&gt;...&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;附录&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;我发现在&lt;span style="font-family: 'Times New Roman';"&gt;LINQ&amp;nbsp;to&amp;nbsp;Objects&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;（官方实现）中，&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Single&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;和&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;SingleOrDefault&lt;/span&gt;&lt;span style="font-family: SimSun;"&gt;没有谓词的重载在遇到第二个元素时马上就会抛出异常。但是有谓词的重载即使遇到了第二个元素，还是会继续遍历。这看起来很是荒唐，没有连贯性。我发了一个&lt;/span&gt;&lt;a href="https://connect.microsoft.com/VisualStudio/feedback/details/639955"&gt;Connect&amp;nbsp;issue&lt;/a&gt;，我们看看会有怎样的答复。&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/cuipengfei/aggbug/2438764.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cuipengfei/archive/2012/04/09/2438764.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cuipengfei/archive/2012/02/15/2352444.html</id><title type="text">自己动手重新实现LINQ to Objects: 10 - Any和All</title><summary type="text">本文翻译自JonSkeet的系列博文“Edulinq”。本篇原文地址：http://msmvps.com/blogs/jon_skeet/archive/2010/12/28/reimplementing-linq-to-objects-part-10-any-and-all.aspx今天我们介绍两个操作符：Any和All。Any和All做什么？Any有两个重载，而All只有一个：public static bool Any&lt;TSource&gt;( this IEnumerable&lt;TSource&gt; source) public static bool Any&lt;TSo</summary><published>2012-02-15T05:35:00Z</published><updated>2012-02-15T05:35:00Z</updated><author><name>崔鹏飞</name><uri>http://www.cnblogs.com/cuipengfei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cuipengfei/archive/2012/02/15/2352444.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cuipengfei/archive/2012/02/15/2352444.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0"&gt;本文翻译自&lt;a href="http://stackoverflow.com/users/22656/jon-skeet"&gt;Jon&amp;nbsp;Skeet&lt;/a&gt;的系列博文&amp;ldquo;&lt;span style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&amp;rdquo;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;本篇原文地址：&lt;/p&gt;&lt;p class="p0"&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2010/12/28/reimplementing-linq-to-objects-part-10-any-and-all.aspx"&gt;http://msmvps.com/blogs/jon_skeet/archive/2010/12/28/reimplementing-linq-to-objects-part-10-any-and-all.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;今天我们介绍两个操作符：Any&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;Any&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;做什么？&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;Any&lt;span style="font-family: 宋体;"&gt;有两个重载，而&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;只有一个：&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; Any&amp;lt;TSource&amp;gt;( &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt; source) &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; Any&amp;lt;TSource&amp;gt;( &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt; source, &lt;br /&gt;&lt;br /&gt;    Func&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt; predicate) &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; All&amp;lt;TSource&amp;gt;( &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt; source, &lt;br /&gt;&lt;br /&gt;    Func&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt; predicate)&lt;/div&gt;&lt;p class="p0"&gt;这两个方法所做的事情完全可以顾名思义：&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;不接受谓词的&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;用于判断输入序列中是否存在任何元素&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;接受谓词的&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;用于判断输入序列中是否存在能够通过谓词检验的元素&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;All&lt;span style="font-family: 宋体;"&gt;用于判断输入序列中的元素是否全部都能通过谓词的检验&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;这两个操作符都是立即执行的，它们在得出最终结果之前不会返回。&lt;/p&gt;&lt;p class="p0"&gt;很重要的一点，&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;必须要迭代整个输入序列才能返回&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，但是它只要遇到一个不能通过谓词检验的元素就会返回&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;false&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;；而&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;只要找到一个可以通过谓词检验的元素就会返回&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，但是必须要迭代整个输入序列才能返回&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;false&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。这就引出了一个很简单的&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;LINQ&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;性能小窍门，下面这种用法几乎在所有情况下都是不可取的：&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Don't use this &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (query.Count() != &lt;span style="color: #800080;"&gt;0&lt;/span&gt;)&lt;/div&gt;&lt;p class="p0"&gt;上面的用法会迭代整个输入序列，如果你只想知道序列中是否含有元素的话，这样来做：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Use this instead &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (query.Any())&lt;/div&gt;&lt;p class="p0"&gt;如果这是一个较大的&lt;span style="font-family: 'Times New Roman';"&gt;LINQ&amp;nbsp;to&amp;nbsp;SQL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;查询中的一部分，那么这两种做法的区别可能不大，但是对于&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;LINQ&amp;nbsp;to&amp;nbsp;Objects&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来说，区别很大。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;我们需要测试什么？&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;我今晚感觉不错，我甚至把参数校验都做了&lt;span style="font-family: 'Times New Roman';"&gt;...&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;虽然说参数校验在这个立即执行的特例下并不困难。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;除此之外，我还测试了以下一些场景：&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;Any&lt;span style="font-family: 宋体;"&gt;作用于空序列应该返回&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;false&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，而&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;则应该返回&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。（因为无论谓词是什么样的，没有任何一个元素会通不过检验。）&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;一个序列，只要它含有元素，不接受谓词的&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;就应该返回&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;如果所有元素都不能通过谓词，那么&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;都应该返回&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;false&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;如果部分元素能够通过谓词，&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;将会返回&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;而&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;会返回&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;false&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;如果所有元素都能够通过谓词，那么&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;会返回&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;以上测试都很简洁明了，我就不给出代码了。还有最后一个测试很有趣：我们要证明&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;会在找到第一个符合条件的元素之后立即返回，证明的手段是通过把&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;作用在一个被完整迭代时会抛出异常的查询结果上。最简单的方式就是创建一个包含有&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;0&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的整数序列，然后对其做&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Select&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;操作，&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Select&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中会把每一个元素除以某个常数。以下的测试用例中，序列中会导致异常的元素之前存在一个能够通过谓词的元素：&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;[Test] &lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; SequenceIsNotEvaluatedAfterFirstMatch() &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;[] src = { &lt;span style="color: #800080;"&gt;10&lt;/span&gt;, &lt;span style="color: #800080;"&gt;2&lt;/span&gt;, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;3&lt;/span&gt; }; &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; query = src.Select(x =&amp;gt; &lt;span style="color: #800080;"&gt;10&lt;/span&gt; / x); &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; This will finish at the second element (x = 2, so 10/x = 5) &lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; It won't evaluate 10/0, which would throw an exception &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;    Assert.IsTrue(query.Any(y =&amp;gt; y &amp;gt; &lt;span style="color: #800080;"&gt;2&lt;/span&gt;)); &lt;br /&gt;&lt;br /&gt;}&lt;/div&gt;&lt;p class="p0"&gt;对于&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，也有一个类似的测试用例，其中会导致异常的元素前面存在一个不能通过谓词检验的元素。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;现在所有测试都有了，下面开始有趣的部分了：&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;来动手实现吧！&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;有一点需要提醒，我们可以基于接受谓词的&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或者基于&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来实现另外两个方法。比如说，如果已经实现了&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的话，那么&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;就可以这样实现：&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; Any&amp;lt;TSource&amp;gt;( &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt; source) &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; source.Any(x =&amp;gt; &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;); &lt;br /&gt;&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; Any&amp;lt;TSource&amp;gt;( &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt; source, &lt;br /&gt;&lt;br /&gt;    Func&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt; predicate) &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (predicate == &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;) &lt;br /&gt;&lt;br /&gt;    { &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;predicate&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;); &lt;br /&gt;&lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; !source.All(x =&amp;gt; !predicate(x)); &lt;br /&gt;&lt;br /&gt;}&lt;/div&gt;&lt;p class="p0"&gt;基于接受谓词的的&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来实现不接受谓词的&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是最简单的，我们使用了一个对任何元素都会返回&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的谓词，这就意味着只要输出序列中含有元素就会返回&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，这正是我们想要的行为。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;上面调用&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;时的两次否操作会让你费点脑筋，不过这其实就是&lt;/span&gt;&lt;a href="http://zh.wikipedia.org/wiki/%E5%BE%B7%E6%91%A9%E6%A0%B9%E5%AE%9A%E5%BE%8B"&gt;德摩根定律&lt;/a&gt;在&lt;span style="font-family: 'Times New Roman';"&gt;LINQ&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的表现形式：我们对谓词做否操作，来检验是否所有的元素都不能通过谓词，得到结果后，再次做否操作并返回。由于否操作的原因，这种实现方式仍然会在合适的情况下提前返回。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;虽然以上的方式可行，但是我更喜欢给每个方法一个单独的实现，这样做简单明了：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; Any&amp;lt;TSource&amp;gt;( &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt; source) &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (source == &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;) &lt;br /&gt;&lt;br /&gt;    { &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;source&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;); &lt;br /&gt;&lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt;             &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; (IEnumerator&amp;lt;TSource&amp;gt; iterator = source.GetEnumerator()) &lt;br /&gt;&lt;br /&gt;    { &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; iterator.MoveNext(); &lt;br /&gt;&lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; Any&amp;lt;TSource&amp;gt;( &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt; source, &lt;br /&gt;&lt;br /&gt;    Func&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt; predicate) &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (source == &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;) &lt;br /&gt;&lt;br /&gt;    { &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;source&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;); &lt;br /&gt;&lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (predicate == &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;) &lt;br /&gt;&lt;br /&gt;    { &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;predicate&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;); &lt;br /&gt;&lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (TSource item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; source) &lt;br /&gt;&lt;br /&gt;    { &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (predicate(item)) &lt;br /&gt;&lt;br /&gt;        { &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;; &lt;br /&gt;&lt;br /&gt;        } &lt;br /&gt;&lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;; &lt;br /&gt;&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; All&amp;lt;TSource&amp;gt;( &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt; source, &lt;br /&gt;&lt;br /&gt;    Func&amp;lt;TSource, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&amp;gt; predicate) &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (source == &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;) &lt;br /&gt;&lt;br /&gt;    { &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;source&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;); &lt;br /&gt;&lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (predicate == &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;) &lt;br /&gt;&lt;br /&gt;    { &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;predicate&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;); &lt;br /&gt;&lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (TSource item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; source) &lt;br /&gt;&lt;br /&gt;    { &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!predicate(item)) &lt;br /&gt;&lt;br /&gt;        { &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;; &lt;br /&gt;&lt;br /&gt;        } &lt;br /&gt;&lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;; &lt;br /&gt;&lt;br /&gt;}&lt;/div&gt;&lt;p class="p0"&gt;这样的实现方式很明显的凸显了&amp;ldquo;提前返回&amp;rdquo;这一特性。而且，这样做也可以使得堆栈跟踪记录更易读。对于一个下游开发者来说，如果调试&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;时在堆栈跟踪记录中看到了调用&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的记录会显得很奇怪；调用&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;时看到了&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;也会很奇怪。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;有一点很有趣，不接受谓词的&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中我们没用到&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;foreach&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。而是用了迭代器第一次调用&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;MoveNext&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法时的返回值来表示序列中是否存在元素。读这个方法可以很明显的（至少对我来说很明显）看出我们根本不关心第一个元素的值是什么，因为我们根本就没有去访问它。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;结论&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;尽量使用&lt;span style="font-family: 'Times New Roman';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;而不是&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的建议或许是这篇文章中最重要的一点，余下的部分都比较简单，不过能基于一个操作符来实现另一个操作符总是很有趣的。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;下一篇讲什么呢？或许是&lt;span style="font-family: 'Times New Roman';"&gt;Single&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;、&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;SingleOrDefault&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;、&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;First&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;、&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;FirstOrDefault&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;、&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Last&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或者&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;LastOrDefault&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。也或许我会把它们都放到一篇文章中来阐释它们的相似同时也强调它们之间的差别。&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/cuipengfei/aggbug/2352444.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cuipengfei/archive/2012/02/15/2352444.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cuipengfei/archive/2011/12/15/2289564.html</id><title type="text">自己动手重新实现LINQ to Objects: 9 - SelectMany</title><summary type="text">本文翻译自JonSkeet的系列博文“Edulinq”。本篇原文地址：http://msmvps.com/blogs/jon_skeet/archive/2010/12/27/reimplementing-linq-to-objects-part-9-selectmany.aspx我们接下来要实现的这个操作符是LINQ中最重要的操作符。大多数（或者是全部？）其他的返回一个序列的操作符都可以通过调用SelectMany来实现，这是后话按下不表。现在我们首先来实现它吧。SelectMany是什么？SelectMany有四个重载，看起来一个比一个吓人：publicstaticIEnumerable&amp;</summary><published>2011-12-15T15:28:00Z</published><updated>2011-12-15T15:28:00Z</updated><author><name>崔鹏飞</name><uri>http://www.cnblogs.com/cuipengfei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cuipengfei/archive/2011/12/15/2289564.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cuipengfei/archive/2011/12/15/2289564.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0"&gt;本文翻译自&lt;a href="http://stackoverflow.com/users/22656/jon-skeet"&gt;Jon&amp;nbsp;Skeet&lt;/a&gt;的系列博文&amp;ldquo;&lt;span style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&amp;rdquo;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;本篇原文地址：&lt;/p&gt;&lt;p class="p0"&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2010/12/27/reimplementing-linq-to-objects-part-9-selectmany.aspx"&gt;http://msmvps.com/blogs/jon_skeet/archive/2010/12/27/reimplementing-linq-to-objects-part-9-selectmany.aspx&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="Section0"&gt;&lt;p class="p0"&gt;我们接下来要实现的这个操作符是LINQ&lt;span style="font-family: 宋体;"&gt;中最重要的操作符。大多数（或者是全部？）其他的返回一个序列的操作符都可以通过调用&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来实现，这是后话按下不表。现在我们首先来实现它吧。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;SelectMany&lt;span style="font-family: 宋体;"&gt;是什么？&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;SelectMany&lt;span style="font-family: 宋体;"&gt;有四个重载，看起来一个比一个吓人：&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;public&amp;nbsp;static&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;SelectMany&amp;lt;TSource,&amp;nbsp;TResult&amp;gt;(&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;gt;&amp;nbsp;selector)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;public&amp;nbsp;static&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;SelectMany&amp;lt;TSource,&amp;nbsp;TResult&amp;gt;(&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;int,&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;gt;&amp;nbsp;selector)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;public&amp;nbsp;static&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;SelectMany&amp;lt;TSource,&amp;nbsp;TCollection,&amp;nbsp;TResult&amp;gt;(&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt;&amp;nbsp;collectionSelector,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;TCollection,&amp;nbsp;TResult&amp;gt;&amp;nbsp;resultSelector)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;public&amp;nbsp;static&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;SelectMany&amp;lt;TSource,&amp;nbsp;TCollection,&amp;nbsp;TResult&amp;gt;(&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;int,&amp;nbsp;IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt;&amp;nbsp;collectionSelector,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;TCollection,&amp;nbsp;TResult&amp;gt;&amp;nbsp;resultSelector)&lt;/p&gt;&lt;p class="p0"&gt;其实还不算太坏，这些重载只是同一个操作的不同形式而已。&lt;/p&gt;&lt;p class="p0"&gt;无论是哪个重载，都需要一个输入序列。然后用一个委托来处理输入序列中的每个元素以生成一个子序列，这个委托可能会接受一个代表元素&lt;span style="font-family: 'Times New Roman';"&gt;index&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的参数。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;再然后，我们或者把每个子序列中的元素直接返回，或者再用另一个委托来做处理，这个委托接受输入序列中的元素并接受其对应的子序列中的元素。&lt;/p&gt;&lt;p class="p0"&gt;以我的经验来说，使用&lt;span style="font-family: 'Times New Roman';"&gt;index&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;两个重载不太常用，而另外两个重载（上面列出的第一个和第三个）则比较常用。还有，当&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;C#&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;编译器处理一个含有多个&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;from&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句的查询表达式的时候，它会把出第一个&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;from&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;之外的其他&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;from&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句转译为上面的第三个重载。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;为了把上面的说法放入实例中理解，我们假设有这样一个查询表达式：&lt;/p&gt;&lt;p class="p0"&gt;var&amp;nbsp;query&amp;nbsp;=&amp;nbsp;from&amp;nbsp;file&amp;nbsp;in&amp;nbsp;Directory.GetFiles("logs")&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;from&amp;nbsp;line&amp;nbsp;in&amp;nbsp;File.ReadLines(file)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;select&amp;nbsp;Path.GetFileName(file)&amp;nbsp;+&amp;nbsp;":&amp;nbsp;"&amp;nbsp;+&amp;nbsp;line;&lt;/p&gt;&lt;p class="p0"&gt;上面的查询表达式会被转译为下面的&amp;ldquo;正常&amp;rdquo;调用：&lt;/p&gt;&lt;p class="p0"&gt;var&amp;nbsp;query&amp;nbsp;=&amp;nbsp;Directory.GetFiles("logs")&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.SelectMany(file&amp;nbsp;=&amp;gt;&amp;nbsp;File.ReadLines(file),&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(file,&amp;nbsp;line)&amp;nbsp;=&amp;gt;&amp;nbsp;Path.GetFileName(file)&amp;nbsp;+&amp;nbsp;":&amp;nbsp;"&amp;nbsp;+&amp;nbsp;line);&lt;/p&gt;&lt;p class="p0"&gt;这个例子中，编译器会把表达式中的&lt;span style="font-family: 'Times New Roman';"&gt;select&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句转译为投影操作；如果表达式后面还跟有&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;where&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句或其他子句，编译器会把&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;file&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;line&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;包装在一个匿名类型中传递给投影操作。这是查询表达式转译中最令人难理解的一点，因为这涉及到了透明标识符（&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;transparent&amp;nbsp;identifiers&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;）。就现在来说，我们只分析上面给出的简单例子。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;上例中的&lt;span style="font-family: 'Times New Roman';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;接受三个参数：&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;输入序列，也就是一个字符串序列（&lt;span style="font-family: 'Times New Roman';"&gt;Directory.GetFiles&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;所返回的文件名）&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;一个初始投影操作，它把一个文件名转化为该文件中包含的一行行的字符串&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;一个结束投影操作，它把一个文件名和一行文件内容转化为一个由冒号分隔的字符串&lt;/p&gt;&lt;p class="p0"&gt;表达式的最后结果会是一个字符串的序列，其中包含所有&lt;span style="font-family: 'Times New Roman';"&gt;log&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;文件的每一行，每一行会以文件名作为前缀。如果把结果打印出来，大概会是这样的：&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;test1.log:&amp;nbsp;foo&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;test1.log:&amp;nbsp;bar&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;test1.log:&amp;nbsp;baz&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;test2.log:&amp;nbsp;Second&amp;nbsp;log&amp;nbsp;file&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;test2.log:&amp;nbsp;Another&amp;nbsp;line&amp;nbsp;from&amp;nbsp;the&amp;nbsp;second&amp;nbsp;log&amp;nbsp;file&lt;/p&gt;&lt;p class="p0"&gt;要理解&lt;span style="font-family: 'Times New Roman';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;可能会费点脑子，我当时理解它就费了点力，不过理解它是很重要的。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;在讲测试之前，还有几点关于&lt;span style="font-family: 'Times New Roman';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的行为细节需要说明：&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;参数校验是立即执行的，每个参数都不能是&lt;span style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;整个过程都是流式处理的。每次只会从输入序列中读取一个元素，然后生成一个子序列。然后每次只会返回子序列中的一个元素，返回子序列中的全部元素之后再去读取输入序列中的下一个元素，用它来生成下一个子序列，如此循环往复。&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;每个迭代器在使用完之后都会被关闭，正如你会预期的一样。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;我们要测试什么呢？&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;我有一点变懒了，我不想再写参数为&lt;span style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的测试了。我给&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的每一个重载都写了一个测试。我发现我无法把这些测试写得很清晰，不过还是拿出一个例子来，下面的代码是针对&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的最复杂的重载的测试：&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;[Test]&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;public&amp;nbsp;void&amp;nbsp;FlattenWithProjectionAndIndex()&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int[]&amp;nbsp;numbers&amp;nbsp;=&amp;nbsp;{&amp;nbsp;3,&amp;nbsp;5,&amp;nbsp;20,&amp;nbsp;15&amp;nbsp;};&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;query&amp;nbsp;=&amp;nbsp;numbers.SelectMany((x,&amp;nbsp;index)&amp;nbsp;=&amp;gt;&amp;nbsp;(x&amp;nbsp;+&amp;nbsp;index).ToString().ToCharArray(),&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(x,&amp;nbsp;c)&amp;nbsp;=&amp;gt;&amp;nbsp;x&amp;nbsp;+&amp;nbsp;":&amp;nbsp;"&amp;nbsp;+&amp;nbsp;c);&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;3&amp;nbsp;=&amp;gt;&amp;nbsp;"3:&amp;nbsp;3"&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;5&amp;nbsp;=&amp;gt;&amp;nbsp;"5:&amp;nbsp;6"&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;20&amp;nbsp;=&amp;gt;&amp;nbsp;"20:&amp;nbsp;2",&amp;nbsp;"20:&amp;nbsp;2"&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;15&amp;nbsp;=&amp;gt;&amp;nbsp;"15:&amp;nbsp;1",&amp;nbsp;"15:&amp;nbsp;8"&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;query.AssertSequenceEqual("3:&amp;nbsp;3",&amp;nbsp;"5:&amp;nbsp;6",&amp;nbsp;"20:&amp;nbsp;2",&amp;nbsp;"20:&amp;nbsp;2",&amp;nbsp;"15:&amp;nbsp;1",&amp;nbsp;"15:&amp;nbsp;8");&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;}&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;给这个测试做一点解释：&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;每一个数字都和它的序号相加&amp;nbsp;&lt;span style="font-family: 'Courier New';"&gt;(3+0,&amp;nbsp;5+1,&amp;nbsp;20+2,&amp;nbsp;15+3)&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;相加的结果转成字符串，然后转成字符数组。（我们原本不需要调用&lt;span style="font-family: 'Courier New';"&gt;ToCharArray&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的，因为&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;String&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;本身就实现了&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;IEnumerable&amp;lt;char&amp;gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，不过现在这样写比较清晰。）&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;l&amp;nbsp;然后把子序列中的每一个字符和原元素以&amp;ldquo;原元素：子序列字符&amp;rdquo;的形式组合在一起&lt;/p&gt;&lt;p class="p0"&gt;注释部分是每一个输入元素对应的输出结果，测试最后一句代码给出了完整的输出序列。&lt;/p&gt;&lt;p class="p0"&gt;是不是一团乱麻？希望你看了上面逐步分解的解释很清楚一点。好了，现在想办法让测试可以通过吧。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;开始动手实现吧！&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;我们可以通过实现一个最复杂的重载并让其他的重载都调用它来实现&lt;span style="font-family: 'Courier New';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，或者也可以写一个没有参数校验的&amp;ldquo;&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;Impl&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&amp;rdquo;方法，然后让四个重载都调用它。比如说，最简单重载可以这样实现：&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;public&amp;nbsp;static&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;SelectMany&amp;lt;TSource,&amp;nbsp;TResult&amp;gt;(&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;gt;&amp;nbsp;selector)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(source&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;ArgumentNullException("source");&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(selector&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;ArgumentNullException("selector");&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;SelectManyImpl(source,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(value,&amp;nbsp;index)&amp;nbsp;=&amp;gt;&amp;nbsp;selector(value),&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(originalElement,&amp;nbsp;subsequenceElement)&amp;nbsp;=&amp;gt;&amp;nbsp;subsequenceElement);&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;}&lt;/p&gt;&lt;p class="p0"&gt;不过我还是选择为每一重载写一个签名相同的&amp;ldquo;&lt;span style="font-family: 'Courier New';"&gt;SelectManyImpl&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&amp;rdquo;方法。我觉得这样做可以让以后单步调试时更简单一些&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;...&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;而且这样让我们可以注意到不同重载之间的区别，代码是这样的：&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;//&amp;nbsp;Simplest&amp;nbsp;overload&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;private&amp;nbsp;static&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;SelectManyImpl&amp;lt;TSource,&amp;nbsp;TResult&amp;gt;(&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;gt;&amp;nbsp;selector)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&amp;nbsp;(TSource&amp;nbsp;item&amp;nbsp;in&amp;nbsp;source)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&amp;nbsp;(TResult&amp;nbsp;result&amp;nbsp;in&amp;nbsp;selector(item))&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;return&amp;nbsp;result;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;//&amp;nbsp;Most&amp;nbsp;complicated&amp;nbsp;overload:&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;//&amp;nbsp;-&amp;nbsp;Original&amp;nbsp;projection&amp;nbsp;takes&amp;nbsp;index&amp;nbsp;as&amp;nbsp;well&amp;nbsp;as&amp;nbsp;value&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;//&amp;nbsp;-&amp;nbsp;There's&amp;nbsp;a&amp;nbsp;second&amp;nbsp;projection&amp;nbsp;for&amp;nbsp;each&amp;nbsp;original/subsequence&amp;nbsp;element&amp;nbsp;pair&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;private&amp;nbsp;static&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;SelectManyImpl&amp;lt;TSource,&amp;nbsp;TCollection,&amp;nbsp;TResult&amp;gt;(&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;int,&amp;nbsp;IEnumerable&amp;lt;TCollection&amp;gt;&amp;gt;&amp;nbsp;collectionSelector,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;TCollection,&amp;nbsp;TResult&amp;gt;&amp;nbsp;resultSelector)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&amp;nbsp;index&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&amp;nbsp;(TSource&amp;nbsp;item&amp;nbsp;in&amp;nbsp;source)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&amp;nbsp;(TCollection&amp;nbsp;collectionItem&amp;nbsp;in&amp;nbsp;collectionSelector(item,&amp;nbsp;index++))&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;return&amp;nbsp;resultSelector(item,&amp;nbsp;collectionItem);&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;}&lt;/p&gt;&lt;p class="p0"&gt;这两个方法之间的相似性很是明显&lt;span style="font-family: 'Courier New';"&gt;...&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;不过我还是觉得保留着第一种形式很有用，如果我搞不清楚&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的作用的话，通过第一种最简单的重载就可以很容易的弄懂。以此为基础再去理解余下的重载，跳跃性就不会那么大了。第一个重载在一定程度上起到了一个理解&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的概念的垫脚石的作用。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;有两点需要指出：&lt;/p&gt;&lt;p class="p0"&gt;如果&lt;span style="font-family: 'Courier New';"&gt;C#&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中可以使用&amp;ldquo;&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;yield&amp;nbsp;foreach&amp;nbsp;selector(item)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&amp;rdquo;这种表达式的话，上面的第一个方法就可以实现的稍简单一点。如果要在第二个方法中使用这种做法的话就会难一些，而且可能还要涉及到对&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的调用，这样的话就有点得不偿失了。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;在第二个方法中，我没有显式的使用&amp;ldquo;&lt;span style="font-family: 'Courier New';"&gt;checked&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&amp;rdquo;代码块，虽然说&amp;ldquo;&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;index&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&amp;rdquo;是有可能溢出的。我没有看过&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;BCL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的实现是什么样的，但是我认为他们不会写&amp;ldquo;&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;checked&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&amp;rdquo;的。考虑到前后一致性，我或许应该在每一个处理&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;index&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的方法中都是用&amp;ldquo;&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;checked&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&amp;rdquo;代码块，或者给整个程序集开启&amp;ldquo;&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;checked&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&amp;rdquo;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;通过调用&lt;span style="font-family: 'Courier New';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来实现其他操作符&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;之前我提到过很多的&lt;span style="font-family: 'Courier New';"&gt;LINQ&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;操作符都可以通过调用&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来实现。下面的代码就是这一观点的实例，我们通过调用&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;实现了&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;Where&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;Concat&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;public&amp;nbsp;static&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;Select&amp;lt;TSource,&amp;nbsp;TResult&amp;gt;(&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;TResult&amp;gt;&amp;nbsp;selector)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(source&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;ArgumentNullException("source");&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(selector&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;ArgumentNullException("selector");&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;source.SelectMany(x&amp;nbsp;=&amp;gt;&amp;nbsp;Enumerable.Repeat(selector(x),&amp;nbsp;1));&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;public&amp;nbsp;static&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;Where&amp;lt;TSource&amp;gt;(&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;bool&amp;gt;&amp;nbsp;predicate)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(source&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;ArgumentNullException("source");&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(predicate&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;ArgumentNullException("predicate");&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;source.SelectMany(x&amp;nbsp;=&amp;gt;&amp;nbsp;Enumerable.Repeat(x,&amp;nbsp;predicate(x)&amp;nbsp;?&amp;nbsp;1&amp;nbsp;:&amp;nbsp;0));&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;public&amp;nbsp;static&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;Concat&amp;lt;TSource&amp;gt;(&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;first,&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;second)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(first&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;ArgumentNullException("first");&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(second&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;ArgumentNullException("second");&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;new[]&amp;nbsp;{&amp;nbsp;first,&amp;nbsp;second&amp;nbsp;}.SelectMany(x&amp;nbsp;=&amp;gt;&amp;nbsp;x);&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;}&lt;/p&gt;&lt;p class="p0"&gt;Select&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;使用&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;Enumerable.Repeat&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来很方便的创建含有一个元素或不包含任何元素的序列。你也可以通过创建一个数组来代替使用&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;Repeat&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的这种做法。&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;Concat&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;直接使用了一个数组：如果你理解了&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的作用就是把多个序列组合为一个序列这一点的话，&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;Concat&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;这样实现看起来就很自然了。我估计&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;Empty&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;Repeat&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;可以通过递归来实现，尽管这样的话性能会很差。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;现在，上面的代码是放在条件编译块里面的。如果大家希望我多写一些借助于&lt;span style="font-family: 'Courier New';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来实现的操作符的话，我可能会考虑把它单独分离一个项目出来。不过我感觉以上的代码已经足以显示&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的灵活性了，再利用&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来实现更多的其他操作符也未必能更加充分的说明这一点。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;在理论的意义上，&lt;span style="font-family: 'Courier New';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;也很重要，因为它为&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;LINQ&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;提供了&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;monadic&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的特性。我不想在这一话题上说的更多，你可以读一读&lt;/span&gt;&lt;a href="http://blogs.msdn.com/b/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx"&gt;Wes&amp;nbsp;Dyer&lt;span style="font-family: 宋体;"&gt;的博客&lt;/span&gt;&lt;/a&gt;，或者直接搜索&amp;ldquo;&lt;span style="font-family: 'Courier New';"&gt;bind&amp;nbsp;monad&amp;nbsp;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&amp;rdquo;就可以找到很多比我更聪明的人写的文章。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;结论&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;SelectMany&lt;span style="font-family: 宋体;"&gt;是&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;LINQ&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的基础之一，初看上去它很是令人生畏。但是一旦你理解了&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;SelectMany&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的作用就是把多个序列组合起来这一点之后，它就很容易搞懂了。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;下一次我们讨论&lt;span style="font-family: 'Courier New';"&gt;All&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span style="font-family: 'Courier New';"&gt;Any&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，这两个操作符很适合放在一起来讲解。&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/cuipengfei/aggbug/2289564.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cuipengfei/archive/2011/12/15/2289564.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cuipengfei/archive/2011/09/14/2176725.html</id><title type="text">自己动手重新实现LINQ to Objects: 8 - Concat</title><summary type="text">本文翻译自JonSkeet的系列博文“Edulinq”。本篇原文地址：http://msmvps.com/blogs/jon_skeet/archive/2010/12/27/reimplementing-linq-to-objects-part-8-concat.aspx上文讲的Count和LongCount返回的是数值类型，本文我们讲的Concat返回的是一个序列。Concat是什么？Concat只有一种签名形式，这让它使用起来很简单：publicstaticIEnumerable&lt;TSource&gt;Concat&lt;TSource&gt;(thisIEnumerable&amp;lt</summary><published>2011-09-14T14:39:00Z</published><updated>2011-09-14T14:39:00Z</updated><author><name>崔鹏飞</name><uri>http://www.cnblogs.com/cuipengfei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cuipengfei/archive/2011/09/14/2176725.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cuipengfei/archive/2011/09/14/2176725.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="Section0"&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本文翻译自&lt;/span&gt;&lt;span&gt;&lt;a href="http://stackoverflow.com/users/22656/jon-skeet"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;Jon&amp;nbsp;Skeet&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;的系列博文&amp;ldquo;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本篇原文地址：&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2010/12/27/reimplementing-linq-to-objects-part-8-concat.aspx"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.5000pt; font-family: 'Times New Roman';"&gt;http://msmvps.com/blogs/jon_skeet/archive/2010/12/27/reimplementing-linq-to-objects-part-8-concat.aspx&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Times New Roman';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Times New Roman';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;上文讲的&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;Count&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LongCount&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;返回的是数值类型，本文我们讲的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Concat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;返回的是一个序列。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;Concat&lt;span face="宋体" style="font-family: 宋体;"&gt;是什么？&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb302894.aspx"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;&lt;br /&gt;Concat&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;只有一种签名形式，这让它使用起来很简单：&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;br /&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;Concat&amp;lt;TSource&amp;gt;(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;first,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;second)&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;Concat&lt;span face="宋体" style="font-family: 宋体;"&gt;的返回值依次包含了两个序列中的元素，也就是说把两个序列串联起来了。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;我有时会觉得&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;.NET&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;没有提供&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Prepend/Append&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;这样的方法是个遗憾，这两个方法应该可以和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Concat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;做类似的事情，只不过它们把一个序列和一个单个的元素串联起来。如果要做一个填充着国家名和一个&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;None&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;值的下拉列表的话，这两个方法是很有用的。当然，向&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Concat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;中传入一个单元素的数组也可以达到同样的目的，但是我个人认为用特定的方法名做特定的事会让代码的可读性更高。&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;a href="http://code.google.com/p/morelinq/"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;MoreLINQ&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;中的&lt;/span&gt;&lt;span&gt;&lt;a href="http://code.google.com/p/morelinq/source/browse/trunk/MoreLinq/Concat.cs?r=171"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;Concat&lt;span face="宋体" style="font-family: 宋体;"&gt;方法&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;可以做这件事，不过&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的目的只是要实现&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LINQ&amp;nbsp;to&amp;nbsp;Objects&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;中已有的方法。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;和往常一样，我们列出&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Concat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的行为：&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;&lt;br /&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;参数校验需要立即执行：两个参数都不允许为&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;返回值是延迟执行的：当&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Concat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;被调用时，两个参数不会立即被迭代&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;输入序列只有在需要的时候才会被迭代：如果你停止迭代输出序列时第一个输入序列还没有被耗尽的话，那么第二个序列根本就不会被迭代&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;这几点描述基本就涵盖了&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Concat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的所有行为。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;我们需要测试什么呢？&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;Concat&lt;span face="宋体" style="font-family: 宋体;"&gt;的串联行为很容易被测试，只需要一个用例就够了。我们或许也可以测试输入空序列会如何，但是那种测试基本没有不通过的可能。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;参数校验的测试方式和往常一样：调用方法时传入非法的参数，然后不去迭代方法的返回值。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;最后，还有一个单元测试用来测试两个输入序列被迭代的时机。这个测试中用到了我们在测试&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Where&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;时用过的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ThrowingEnumerable&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;：&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;br /&gt;[Test]&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;void&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;FirstSequenceIsntAccessedBeforeFirstUse()&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerable&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;&amp;nbsp;first&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;ThrowingEnumerable();&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerable&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;&amp;nbsp;second&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;[]&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;5&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;};&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;No&amp;nbsp;exception&amp;nbsp;yet...&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;query&amp;nbsp;=&amp;nbsp;first.Concat(second);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;Still&amp;nbsp;no&amp;nbsp;exception...&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;using&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(var&amp;nbsp;iterator&amp;nbsp;=&amp;nbsp;query.GetEnumerator())&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;Now&amp;nbsp;it&amp;nbsp;will&amp;nbsp;go&amp;nbsp;bang&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.Throws&amp;lt;InvalidOperationException&amp;gt;(()&amp;nbsp;=&amp;gt;&amp;nbsp;iterator.MoveNext());&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;[Test]&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;void&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;SecondSequenceIsntAccessedBeforeFirstUse()&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerable&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;&amp;nbsp;first&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;[]&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;5&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;};&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerable&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;&amp;nbsp;second&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;ThrowingEnumerable();&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;No&amp;nbsp;exception&amp;nbsp;yet...&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;query&amp;nbsp;=&amp;nbsp;first.Concat(second);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;Still&amp;nbsp;no&amp;nbsp;exception...&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;using&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(var&amp;nbsp;iterator&amp;nbsp;=&amp;nbsp;query.GetEnumerator())&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;First&amp;nbsp;element&amp;nbsp;is&amp;nbsp;fine...&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.IsTrue(iterator.MoveNext());&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.AreEqual(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;5&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;iterator.Current);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;Now&amp;nbsp;it&amp;nbsp;will&amp;nbsp;go&amp;nbsp;bang,&amp;nbsp;as&amp;nbsp;we&amp;nbsp;move&amp;nbsp;into&amp;nbsp;the&amp;nbsp;second&amp;nbsp;sequence&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.Throws&amp;lt;InvalidOperationException&amp;gt;(()&amp;nbsp;=&amp;gt;&amp;nbsp;iterator.MoveNext());&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;我们写测试来检查迭代器是否被&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Dispose&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;掉了。但是我们可以预测到输入序列的迭代器应该会被合理的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Dispose&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;掉。实际上，第一个序列的迭代器会在第二个序列开始被迭代之前就被&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Dispose&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;掉。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;开始动手实现吧！&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;Concat&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现虽然比较简单，但是我写完之后还是觉得&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;F#&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;更值得拥有&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;...&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;实现分为参数校验和迭代器代码块两部分，每一部分都不复杂：&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;br /&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;Concat&amp;lt;TSource&amp;gt;(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;first,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;second)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;if&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(first&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;ArgumentNullException(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"first"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;if&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(second&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;ArgumentNullException(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"second"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;ConcatImpl(first,&amp;nbsp;second);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;private&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;ConcatImpl&amp;lt;TSource&amp;gt;(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;first,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;second)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&amp;nbsp;(TSource&amp;nbsp;item&amp;nbsp;in&amp;nbsp;first)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;item;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&amp;nbsp;(TSource&amp;nbsp;item&amp;nbsp;in&amp;nbsp;second)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;item;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;如果不能利用迭代器代码块的话，这个实现会变得很麻烦。虽然不会特别难，但是我们需要记住当前正在迭代的是哪个序列。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;如果是在用&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;F#&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的话，我们可以使用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;yield!&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;表达式来把它实现的更简单，&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;yield!&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;表达式作用于一整个序列而不是单个的元素。必需得承认在这种场景下使用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;yield!&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;并不会带来什么性能上的提升（如果是在递归的场景下就很可能会有性能提升），但是能够用一个语句来&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;yield&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;返回整个序列确实是一种更优雅的风格。（&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Spec#&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;中也有一个类似的结构叫做嵌套迭代器，用&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;a href="http://research.microsoft.com/en-us/projects/specsharp/iterators.pdf"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;yield&amp;nbsp;foreach&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;来表示。）我对&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;F#&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Spec#&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;了解的都不够深入，所以就不做更深入的比较了。不过我们在以后实现&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的过程中还会遇到好几次&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;yield&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;返回一个序列中的每个元素&amp;rdquo;的模式。请记住，我们不能把&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;yield&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;返回的代码抽取到一个单独的方法中去，因为&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;yield&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;表达式需要&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;C#&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;编译器的特殊处理。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;结论&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;虽然我用的实现方式还是蛮简单的，但是我还是吐槽一下：）&amp;nbsp;如果&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;C#&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;里面也有嵌套迭代器那多好啊，虽然说没有它也没有令我太苦恼。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;Concat&lt;span face="宋体" style="font-family: 宋体;"&gt;是一个很有用的操作符，不过它也不过是&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;SelectMany&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的一个特例罢了。&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Concat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;只能把两个序列连接成一个序列，而&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;SelectMany&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;则可以把很多个序列连接成一个序列，而且&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;SelectMany&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;在有时还更有普遍性。下次我们会实现&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;SelectMany&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，而且会展示一些基于&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;SelectMany&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;来实现其他操作符的例子。（等实现&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Aggregate&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的时候，我们会再次见到操作符只返回一个值的例子。）&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;附录：避免不必要的保持引用&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;有一条留言建议说要在遍历完第一个序列后把它设为&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。这样，在遍历完第一个序列后，它就可以被垃圾回收了。如果采取这个建议，那么实现起来会是这样的：&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;private&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;ConcatImpl&amp;lt;TSource&amp;gt;(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;first,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;second)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&amp;nbsp;(TSource&amp;nbsp;item&amp;nbsp;in&amp;nbsp;first)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;item;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;Avoid&amp;nbsp;hanging&amp;nbsp;onto&amp;nbsp;a&amp;nbsp;reference&amp;nbsp;we&amp;nbsp;don't&amp;nbsp;really&amp;nbsp;need&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;first&amp;nbsp;=&amp;nbsp;null;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&amp;nbsp;(TSource&amp;nbsp;item&amp;nbsp;in&amp;nbsp;second)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;item;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;在普通情况下，把一个不再使用的局部变量设为&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;这种做法是没用的。因为当&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;CLR&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;在执行优化过的代码，并且没有挂上调试器时，垃圾收集器只关心在方法内部可能还会被访问的变量。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;但是在我们这个特例中，这么做还是有用的。因为第一个参数并不是一个简单的局部变量，在&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;C#&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;编译器生成的隐藏类型中，它是一个实例字段，而&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;CLR&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;无法判断实例字段是否会被再次使用。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;或许我们可以在调用&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;GetEnumerator&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;之前清空掉我们对&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;first&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;这个参数的唯一引用。我们可以写一个这样的方法：&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;T&amp;nbsp;ReturnAndSetToNull&amp;lt;T&amp;gt;(ref&amp;nbsp;T&amp;nbsp;value)&amp;nbsp;where&amp;nbsp;T&amp;nbsp;:&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;class&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T&amp;nbsp;tmp&amp;nbsp;=&amp;nbsp;value;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value&amp;nbsp;=&amp;nbsp;null;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;tmp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;然后这样调用它：&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;foreach&amp;nbsp;(TSource&amp;nbsp;item&amp;nbsp;in&amp;nbsp;ReturnAndSetToNull(ref&amp;nbsp;first))&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;我认为这样做绝对是有点过了，因为迭代器有可能还会持有对集合的引用。不过在遍历之后把&amp;ldquo;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;first&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;这个参数设为&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;在我看来是说得通的。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;需要提醒你一下，我觉得&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;.NET&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LINQ&amp;nbsp;to&amp;nbsp;Objects&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现里面是不会这样做的。（以后我可能会用一个有&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;finalizer&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的集合类来测试一下。）&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/cuipengfei/aggbug/2176725.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cuipengfei/archive/2011/09/14/2176725.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cuipengfei/archive/2011/09/02/2163273.html</id><title type="text">自己动手重新实现LINQ to Objects: 7 - Count和LongCount</title><summary type="text">本文翻译自JonSkeet的系列博文“Edulinq”。本篇原文地址：http://msmvps.com/blogs/jon_skeet/archive/2010/12/26/reimplementing-linq-to-objects-part-7-count-and-longcount.aspx今天的文章要介绍两个LINQ操作符，因为它们实在是太类似了，所以放到一起来讲。Count和LongCount的实现非常相像，不同的只是方法名，返回值类型和几个变量。Count和LongCount是什么呢？Count和LongCount各自有两个重载：一个重载接受谓词，另一个不接受。下面是这四个方法的</summary><published>2011-09-02T00:01:00Z</published><updated>2011-09-02T00:01:00Z</updated><author><name>崔鹏飞</name><uri>http://www.cnblogs.com/cuipengfei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cuipengfei/archive/2011/09/02/2163273.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cuipengfei/archive/2011/09/02/2163273.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本文翻译自&lt;/span&gt;&lt;span&gt;&lt;a href="http://stackoverflow.com/users/22656/jon-skeet"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;Jon&amp;nbsp;Skeet&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;的系列博文&amp;ldquo;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本篇原文地址：&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2010/12/26/reimplementing-linq-to-objects-part-7-count-and-longcount.aspx"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.5000pt; font-family: 'Times New Roman';"&gt;http://msmvps.com/blogs/jon_skeet/archive/2010/12/26/reimplementing-linq-to-objects-part-7-count-and-longcount.aspx&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="Section0"&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;今天的文章要介绍两个&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;LINQ&lt;span face="宋体" style="font-family: 宋体;"&gt;操作符，因为它们实在是太类似了，所以放到一起来讲。&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LongCount&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现非常相像，不同的只是方法名，返回值类型和几个变量。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;Count&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LongCount&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;是什么呢？&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.count.aspx"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;&lt;br /&gt;Count&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;和&lt;/span&gt;&lt;span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.longcount.aspx"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;LongCount&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;各自有两个重载：一个重载接受谓词，另一个不接受。下面是这四个方法的签名：&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;br /&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;Count&amp;lt;TSource&amp;gt;(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;Count&amp;lt;TSource&amp;gt;(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;bool&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;&amp;nbsp;predicate)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;long&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;LongCount&amp;lt;TSource&amp;gt;(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;long&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;LongCount&amp;lt;TSource&amp;gt;(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;bool&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;&amp;nbsp;predicate)&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;可以看到，&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LongCount&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的方法签名的差别仅在于返回值类型，一个是&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;int&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;（&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Int32&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;），一个是&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;long&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;（&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Int64&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;）。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;不接受谓词的重载返回输入序列中元素的个数；而接受谓词的重载则返回能够通过谓词验证的元素的个数。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;这些方法有一些有趣的行为：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;这四个方法都是扩展&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的方法，你有可能会认为对于不接受谓词的那个重载来说，扩展&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;IEnumerable&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;会来得更好，因为没有什么会限制元素的类型。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;Count&lt;span face="宋体" style="font-family: 宋体;"&gt;的不接受谓词的那个重载对于&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;（&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;.NET4&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;中的接口）做了优化，因为这两个接口都定义有&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;这个属性，这个属性的实现应该比遍历整个集合要快。&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LongCount&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;则没有做优化，稍后的一节中我将会谈到这点。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;接受谓词的重载中没有做任何优化，因为不迭代每一个元素就无法知道到底有多少个元素可以通过谓词的检验。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;这四个方法都是立即执行的，都不涉及延迟执行。（仔细想想就明白了，这些方法仅仅返回一个&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;int&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;或&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;long&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;值，确实没什么可延迟执行的）。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;所有的参数都只做非&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的校验。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;当输入集合的元素个数超出了&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;int&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;或&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;long&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的上限值时，应该抛出&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;OverflowException&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;我们要测试什么呢？&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;我们需要对方法的优化做测试，这件事做起来比说起来难，因为我们需要测试以下四种情况：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;输入序列同时实现了&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;（这个简单，直接用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;List&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;）&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;输入序列实现了&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;但没有实现&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;（还算简单，可以用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;HashSet&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;）&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;输入序列实现了&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;但没有实现&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，我还要要求这个类型实现了&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;（这样才能用到我们的扩展方法）。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;输入序列既不实现&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;也不实现&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;（简单，用我们已经实现了的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;来生成）&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;其中第三点比较麻烦。虽然有很多类型是实现了&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;但没有实现&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的（比如&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ArrayList&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;），但是它们通常也不实现&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，而我们的扩展方法是针对于&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的。所以我只得自己写了一个叫做&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;SemiGenericCollection&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的类。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;上述的四种输入序列的类型都找到了，我们现在需要考虑到底怎么测试了。你可能会说我们可以通过检查输入序列是否被迭代过来测试方法是不是真的被优化了。但是要做这个测试就需要写一个有&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;值但是其&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;GetEnumerator&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;方法会抛异常的集合类型。这个测试确实可行，但是我并没有做它。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;对于接受谓词的重载来说，我们无需考虑那几个不同的集合接口，因为我们反正都不会优化这两个方法。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;参数值为&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的几个测试都比较简单，但是有另一个测试比较重要：溢出。我给&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;创建了一个检验溢出行为的单元测试。很不幸，我们现在还不能在&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的环境里运行它，因为我们还没有实现&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Concat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。不过我还是把它写在这里：&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;br /&gt;[Test]&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;[Ignore(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"Takes&amp;nbsp;an&amp;nbsp;enormous&amp;nbsp;amount&amp;nbsp;of&amp;nbsp;time!"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;)]&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;void&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;Overflow()&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;largeSequence&amp;nbsp;=&amp;nbsp;Enumerable.Range(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;0&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;.MaxValue)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Concat(Enumerable.Range(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;0&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;1&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;));&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.Throws&amp;lt;OverflowException&amp;gt;(()&amp;nbsp;=&amp;gt;&amp;nbsp;largeSequence.Count());&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;如果&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现在应该抛出异常的时候把返回值溢出到了&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Int.MinValue&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的话，这个测试可以发现到它。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;你可以看到，即使在实现了&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Concat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;并反注释了这段代码之后，这个测试也是被忽略掉了的，因为它需要遍历&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;20&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;亿个元素，对于几个简单快速的单元测试来说，这可不妙。其实&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;20&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;亿还不算太坏，因为&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LongCount&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的溢出测试需要遍历&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;2&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;63&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;次方个元素呢。要生成那么长的序列并不难，难的是遍历它，那要花很长的时间。对于接受谓词的重载来说，我们也需要做溢出测试，直到写这篇文章之前我都忘记了要写这个测试，而写测试的时候还发现了一个方法实现中的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;bug&amp;nbsp;:)&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;来动手实现吧！&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;我们来看看接受谓词的那个重载的实现吧，它其实挺简单的：&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;br /&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;Count&amp;lt;TSource&amp;gt;(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;bool&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;&amp;nbsp;predicate)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;if&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(source&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;ArgumentNullException(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"source"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;if&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(predicate&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;ArgumentNullException(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"predicate"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;No&amp;nbsp;way&amp;nbsp;of&amp;nbsp;optimizing&amp;nbsp;this&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;checked&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;count&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;0&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&amp;nbsp;(TSource&amp;nbsp;item&amp;nbsp;in&amp;nbsp;source)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;if&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(predicate(item))&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count++;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;count;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;请注意，在这里我们不需要返回一个序列，所以就没有用到迭代器代码块，因而也就无需把实现拆分到两个方法中去。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;参数校验之后的方法主体部分相当简单，只有一点需要注意：整个的迭代过程都在&amp;ldquo;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;checked&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;代码块中。这样，如果&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;值溢出的话，就会抛出异常，而不会令&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;值成为负数。也有其他的方式可以实现这点：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;可以只把给&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;加一的代码放在&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;checked&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;代码块中。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;可以在每次给&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;加一之前检查&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count==int.MaxValue&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，如果确实相等，则抛出异常&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;可以给整个程序集都应用&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;checked&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;我觉得把这段代码显式的放在&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;checked&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;代码块中是很有益的，因为这样可以很明显的凸显出对溢出的检查是方法正确性的需求这一事实。你可能更倾向于只把&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count++&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;这一句代码放在&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;checked&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;代码块中，不过我个人觉得现在的做法更容易引起读代码的人对&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;checked&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的注意，当然这只是我的主观偏好。还有，显式的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;checked&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;代码块有可能会快一些，这一点我不确定，我还没有测试过。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;除了与谓词有关的部分，上面的代码会全部出现在&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的优化过的实现中，我们就不再讲解了，直接写出代码：&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;br /&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;Count&amp;lt;TSource&amp;gt;(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;if&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(source&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;ArgumentNullException(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"source"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;Optimization&amp;nbsp;for&amp;nbsp;ICollection&amp;lt;T&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ICollection&amp;lt;TSource&amp;gt;&amp;nbsp;genericCollection&amp;nbsp;=&amp;nbsp;source&amp;nbsp;as&amp;nbsp;ICollection&amp;lt;TSource&amp;gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;if&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(genericCollection&amp;nbsp;!=&amp;nbsp;null)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;genericCollection.Count;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;Optimization&amp;nbsp;for&amp;nbsp;ICollection&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ICollection&amp;nbsp;nonGenericCollection&amp;nbsp;=&amp;nbsp;source&amp;nbsp;as&amp;nbsp;ICollection;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;if&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(nonGenericCollection&amp;nbsp;!=&amp;nbsp;null)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;nonGenericCollection.Count;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;Do&amp;nbsp;it&amp;nbsp;the&amp;nbsp;slow&amp;nbsp;way&amp;nbsp;-&amp;nbsp;and&amp;nbsp;make&amp;nbsp;sure&amp;nbsp;we&amp;nbsp;overflow&amp;nbsp;appropriately&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;checked&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;count&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;0&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;using&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(var&amp;nbsp;iterator&amp;nbsp;=&amp;nbsp;source.GetEnumerator())&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;while&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(iterator.MoveNext())&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count++;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;count;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;这个实现里面唯一的&amp;ldquo;新&amp;rdquo;代码就是关于优化的那段。优化代码中的两段基本是一样的，它们检查不同的集合接口类型，哪个检查通过就返回哪个的&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;属性。我不知道&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;.NET&amp;nbsp;Framework&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现中是先检查&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;还是先检查&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，我可以写一个同时实现了这两个接口，但是在两个&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;属性中返回不同的值的类型来测试一下，但是那么做有点太过了。对于良好实现的集合来说，这点性能差异算不了什么，我们先检查&amp;ldquo;最有可能&amp;rdquo;的接口，也就是泛型的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;优化还是不优化？&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;LongCount&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现几乎完全一样，只是&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LongCount&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;中使用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;long&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;而不是&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;int&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;我对&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;做了优化，但是我不认为&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;.NET&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;是如此实现的。（只要创建一个很大的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;byte&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;数组，并比较一下&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LongCount&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;应用到这个数组上的耗时差距就可以了。）&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;关于&lt;/span&gt;&lt;span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.array.getlonglength.aspx"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;Array.GetLongCount&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;的使用存在一些争议，但是我觉得既然现在的&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;CLR&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;并不支持长度超过&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Int32.MaxValue&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的数组，那么这个问题现在就没什么好争议的，只有留待以后证明。除此之外，我不知道&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;.NET&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现为什么没有优化。对一个实现了&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;或&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ICollection&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;接口的类型来说，如果该集合中包含了超过&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Int32.MaxValue&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;个元素的话，它的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;属性应该返回什么值呢？这一点并不明确。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;欢迎提出各种建议。不过我还是要指出&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LongCount&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;方法可能会更多的应用在&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Queryable&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;中而不是&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Enumerable&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;中，获取一个数据库表的长度的场景会比较多见，而获取一个内存中的集合的长度的场景则不那么常见。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;结论&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;这是我们第一次接触返回数值而不是返回一个序列的&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LINQ&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;操作符，很自然，这样的操作符更容易理解。这些方法很简单的执行，做一些优化，然后返回结果值。这些方法虽然简单，但是还是有一些东西很值得思考，比如说优化的问题，可惜优化的问题并没有一个确定的答案。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;下一次我想我会去实现&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Concat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，主要是因为实现了&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Concat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;就可以把对&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;进行溢出测试的代码反注释了。&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Concat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;是一个会返回一个序列的操作符，不过它很简单。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/cuipengfei/aggbug/2163273.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cuipengfei/archive/2011/09/02/2163273.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cuipengfei/archive/2011/08/31/2160844.html</id><title type="text">浅析延迟执行--实现，优点，陷阱以及题外话</title><summary type="text">上周五在公司内部做了一个小型的sharing，讨论了一些与延迟执行有关的东西。现在把ppt和代码分享出来。如有谬误，请不吝指教 :)</summary><published>2011-08-31T08:02:00Z</published><updated>2011-08-31T08:02:00Z</updated><author><name>崔鹏飞</name><uri>http://www.cnblogs.com/cuipengfei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cuipengfei/archive/2011/08/31/2160844.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cuipengfei/archive/2011/08/31/2160844.html"/><content type="html">&lt;p&gt;上周五在公司内部做了一个小型的sharing，讨论了一些与延迟执行有关的东西。现在把ppt和代码分享出来。如有谬误，请不吝指教 :)&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;代码在这儿：&amp;nbsp;&lt;a href="http://codeformyblog.codeplex.com/SourceControl/changeset/view/62764#1095173"&gt;http://codeformyblog.codeplex.com/SourceControl/changeset/view/62764#1095173&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;ppt在这儿：&lt;/p&gt;&lt;div style="width: 595px;" id="__ss_9002119"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/cuipengfei/deferred-execution-9002119" title="Deferred execution" target="_blank"&gt;Deferred execution&lt;/a&gt;&lt;/strong&gt; &lt;iframe width="595" height="497" src="http://www.slideshare.net/slideshow/embed_code/9002119" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;div style="padding: 5px 0 12px;"&gt;View more &lt;a href="http://www.slideshare.net/" target="_blank"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/cuipengfei" target="_blank"&gt;cuipengfei&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/cuipengfei/aggbug/2160844.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cuipengfei/archive/2011/08/31/2160844.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cuipengfei/archive/2011/08/24/2152593.html</id><title type="text">自己动手重新实现LINQ to Objects: 6 - Repeat</title><summary type="text">本文翻译自JonSkeet的系列博文“Edulinq”。本篇原文地址：http://msmvps.com/blogs/jon_skeet/archive/2010/12/24/reimplementing-linq-to-objects-part-6-repeat.aspx本文的主题是个无关紧要的方法，Repeat。关于Repeat，值得讨论的内容比Empty还要少。写这篇博文只是为了保证这个系列的完整性。Repeat是什么？Repeat是一个静态的泛型方法，不是扩展方法，它只有一个签名形式：publicstaticIEnumerable&lt;TResult&gt;Repeat&lt;TRe</summary><published>2011-08-24T14:15:00Z</published><updated>2011-08-24T14:15:00Z</updated><author><name>崔鹏飞</name><uri>http://www.cnblogs.com/cuipengfei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cuipengfei/archive/2011/08/24/2152593.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cuipengfei/archive/2011/08/24/2152593.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本文翻译自&lt;/span&gt;&lt;span&gt;&lt;a href="http://stackoverflow.com/users/22656/jon-skeet"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;Jon&amp;nbsp;Skeet&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;的系列博文&amp;ldquo;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本篇原文地址：&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2010/12/24/reimplementing-linq-to-objects-part-6-repeat.aspx"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.5000pt; font-family: 'Times New Roman';"&gt;http://msmvps.com/blogs/jon_skeet/archive/2010/12/24/reimplementing-linq-to-objects-part-6-repeat.aspx&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size: 10.5pt;"&gt;&lt;span face="'Times New Roman'" style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="Section0"&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本文的主题是个无关紧要的方法，&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;Repeat&lt;span face="宋体" style="font-family: 宋体;"&gt;。关于&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Repeat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，值得讨论的内容比&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Empty&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;还要少。写这篇博文只是为了保证这个系列的完整性。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;Repeat&lt;span face="宋体" style="font-family: 宋体;"&gt;是什么？&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;Repeat&lt;span face="宋体" style="font-family: 宋体;"&gt;是一个静态的泛型方法，不是扩展方法，它只有一个签名形式：&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;br /&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;Repeat&amp;lt;TResult&amp;gt;(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TResult&amp;nbsp;element,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;count)&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;它返回一个序列，该序列中反复的包含&amp;ldquo;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;个指定的元素，。&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Repeat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;只需要一个参数校验：检验&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;不是负数。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;我们要测试什么呢？&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;需要测试的东西真的不多。我只想到了四个场景：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-left: 21pt; text-indent: -21pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;一个简单的测试，把一个字符串重复三次&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-left: 21pt; text-indent: -21pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;一个空序列（把一个元素重复&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;0&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;次）&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-left: 21pt; text-indent: -21pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;一个多次包含&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的序列（仅仅是为了证明&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;element&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;可以为&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;）&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-left: 21pt; text-indent: -21pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;用负数作为&amp;ldquo;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;来证明参数校验会被执行，而且是立即执行的&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;以上这几点恐怕都不怎么令人兴起。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;来动手实现吧！&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;在实现的时候我们唯一有可能做错的事就是把参数校验的代码和迭代器代码块写到一起。不过我们已经多次的做过&amp;ldquo;分割实现&amp;rdquo;了，所以我们肯定不会犯这个错误的。下面的代码就是乏善可陈的&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Repeat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;方法的全部了：&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;br /&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;Repeat&amp;lt;TResult&amp;gt;(TResult&amp;nbsp;element,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;count)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;if&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(count&amp;nbsp;&amp;lt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;0&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;ArgumentOutOfRangeException(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"count"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;RepeatImpl(element,&amp;nbsp;count);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;private&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;RepeatImpl&amp;lt;TResult&amp;gt;(TResult&amp;nbsp;element,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;count)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;for&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;i&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;0&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;count;&amp;nbsp;i++)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;element;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;这就是今天的全部内容了。其中值得指出的部分就是&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;...&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;没有什么值得指出的。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;br /&gt;结论&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;/div&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="font-size: 10.5pt;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 宋体;"&gt;&lt;br /&gt;其实没有什么结论可写。下一次我们讲&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LongCount&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，那里面倒是有些有趣的东西可以细说。&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10.5pt;"&gt;&lt;span face="'Times New Roman'" style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/cuipengfei/aggbug/2152593.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cuipengfei/archive/2011/08/24/2152593.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cuipengfei/archive/2011/08/23/2151375.html</id><title type="text">自己动手重新实现LINQ to Objects: 5 - Empty</title><summary type="text">本文翻译自JonSkeet的系列博文“Edulinq”。本篇原文地址：http://msmvps.com/blogs/jon_skeet/archive/2010/12/24/reimplementing-linq-to-objects-part-5-empty.aspx这一篇继续讲非扩展方法。这次我们要讲的是Empty，它有可能是最简单的LINQ操作符了。Empty是什么？Empty是一个泛型的，静态的方法，它只有一个签名形式，不接受任何参数：publicstaticIEnumerable&lt;TResult&gt;Empty&lt;TResult&gt;()它返回一个特定类型的空序列。这</summary><published>2011-08-23T15:23:00Z</published><updated>2011-08-23T15:23:00Z</updated><author><name>崔鹏飞</name><uri>http://www.cnblogs.com/cuipengfei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cuipengfei/archive/2011/08/23/2151375.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cuipengfei/archive/2011/08/23/2151375.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本文翻译自&lt;/span&gt;&lt;span&gt;&lt;a href="http://stackoverflow.com/users/22656/jon-skeet"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;Jon&amp;nbsp;Skeet&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;的系列博文&amp;ldquo;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本篇原文地址：&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2010/12/24/reimplementing-linq-to-objects-part-5-empty.aspx"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.5000pt; font-family: 'Times New Roman';"&gt;http://msmvps.com/blogs/jon_skeet/archive/2010/12/24/reimplementing-linq-to-objects-part-5-empty.aspx&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size: 10.5pt;"&gt;&lt;span face="'Times New Roman'" style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="Section0"&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;这一篇继续讲非扩展方法。这次我们要讲的是&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;Empty&lt;span face="宋体" style="font-family: 宋体;"&gt;，它有可能是最简单的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LINQ&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;操作符了。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;Empty&lt;span face="宋体" style="font-family: 宋体;"&gt;是什么？&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb341042.aspx"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;Empty&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;是一个泛型的，静态的方法，它只有一个签名形式，不接受任何参数：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;Empty&amp;lt;TResult&amp;gt;()&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;它返回一个特定类型的空序列。这就是它的唯一作用。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;它的行为只有一点比较有趣：文档上说&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Empty&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;会对空序列做缓存。换句话说，对于同一个类型参数来讲，它每次都会返回同一个空序列。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;我们要测试什么？&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;能够测试的东西也就只有两点：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-left: 21pt; text-indent: -21pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;返回序列为空。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-left: 21pt; text-indent: -21pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;对每个类型参数来说，返回值会被缓存起来。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;和测试&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的时候的方法一样，我们用一个叫做&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;EmptyClass&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的别名来引用包含&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Empty&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的类型。下面是测试代码：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;[Test]&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;void&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;EmptyContainsNoElements()&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;using&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(var&amp;nbsp;empty&amp;nbsp;=&amp;nbsp;EmptyClass.Empty&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;().GetEnumerator())&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.IsFalse(empty.MoveNext());&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;[Test]&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;void&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;EmptyIsASingletonPerElementType()&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.AreSame(EmptyClass.Empty&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;(),&amp;nbsp;EmptyClass.Empty&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;());&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.AreSame(EmptyClass.Empty&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;long&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;(),&amp;nbsp;EmptyClass.Empty&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;long&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;());&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.AreSame(EmptyClass.Empty&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;string&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;(),&amp;nbsp;EmptyClass.Empty&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;string&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;());&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.AreSame(EmptyClass.Empty&amp;lt;object&amp;gt;(),&amp;nbsp;EmptyClass.Empty&amp;lt;object&amp;gt;());&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.AreNotSame(EmptyClass.Empty&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;long&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;(),&amp;nbsp;EmptyClass.Empty&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;());&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.AreNotSame(EmptyClass.Empty&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;string&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;(),&amp;nbsp;EmptyClass.Empty&amp;lt;object&amp;gt;());&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;当然，以上代码并不能证明缓存不是每个线程一份。不过，这些测试也够了。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;来动手实现吧！&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;现在看来，&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Empty&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现要比它的描述更有趣。如果不是要做缓存，我们可以这样实现&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Empty&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;Doesn't&amp;nbsp;cache&amp;nbsp;the&amp;nbsp;empty&amp;nbsp;sequence&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;Empty&amp;lt;TResult&amp;gt;()&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;break&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;不过我们需要遵守关于缓存的文档。要实现缓存其实也不难。有一个很方便的事实可以为我们所用，&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;空数组是不可变的&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;。数组的长度是固定的，通常无法使一个数组是只读的。数组中的任何一个元素都是可以改变的。不过一个空数组是不包含任何元素的，所以也就没有什么可被改变的。这样，我们就可以反复的重用同一个数组了。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;现在你可能会猜我会用&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Dictionary&amp;lt;Type,&amp;nbsp;Array&amp;gt;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;来实现，不过我们可以利用一个小手段。在一个泛型类型中，可以用一个静态变量来实现针对类型参数的缓存，因为每一个传入了类型参数的泛型类型的静态变量都是不同的。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;很不幸，&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Empty&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;是一个非泛型类型中的方法。所以我们需要创建另一个泛型类型来包含缓存。这很容易做到，而且&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;CLR&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;还帮我们做到了线程安全的类型初始化。所以，我们最后的实现会是这样的：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;Empty&amp;lt;TResult&amp;gt;()&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;EmptyHolder&amp;lt;TResult&amp;gt;.Array;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;private&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;class&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;EmptyHolder&amp;lt;T&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;internal&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;readonly&amp;nbsp;T[]&amp;nbsp;Array&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;T[&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;0&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;];&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;以上的实现遵守了所有的关于缓存的文档，而且代码行数也很少。不过这个实现方式需要你很好的了解&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;.NET&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;中泛型的工作方式。这种做法和我们上一篇采取的策略相反，我们选择了一种比较难懂的方式，而没有选择使用字典的易懂的方式。不过我很满意这种方案，因为一旦你了解了泛型类型和静态变量的工作方式，这段代码就很简单了。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;结论&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;Empty&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现就是这样的。下一个操作符&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Repeat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;有可能会更简单，虽然它也要分成两个方法来实现。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;附录&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;因为以上讲解的方法有点难懂，所以下面再提供另一种实现：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;Empty&amp;lt;TResult&amp;gt;()&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;EmptyEnumerable&amp;lt;TResult&amp;gt;.Instance;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;#if&amp;nbsp;AVOID_RETURNING_ARRAYS&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;private&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;class&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;EmptyEnumerable&amp;lt;T&amp;gt;&amp;nbsp;:&amp;nbsp;IEnumerable&amp;lt;T&amp;gt;,&amp;nbsp;IEnumerator&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;internal&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;T&amp;gt;&amp;nbsp;Instance&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;EmptyEnumerable&amp;lt;T&amp;gt;();&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;Prevent&amp;nbsp;construction&amp;nbsp;elsewhere&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;private&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;EmptyEnumerable()&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerator&amp;lt;T&amp;gt;&amp;nbsp;GetEnumerator()&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerator&amp;nbsp;IEnumerable.GetEnumerator()&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;T&amp;nbsp;Current&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;{&amp;nbsp;throw&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;InvalidOperationException();&amp;nbsp;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;object&amp;nbsp;IEnumerator.Current&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;{&amp;nbsp;throw&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;InvalidOperationException();&amp;nbsp;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;void&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;Dispose()&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;No-op&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;bool&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;MoveNext()&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;false&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;There's&amp;nbsp;never&amp;nbsp;a&amp;nbsp;next&amp;nbsp;entry&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;void&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;Reset()&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;No-op&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;#else&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;private&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;class&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;EmptyEnumerable&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;internal&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;readonly&amp;nbsp;T[]&amp;nbsp;Instance&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;T[&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;0&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;];&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="font-family: 'Times New Roman'; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;#endif&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="font-size: 10.5pt;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 宋体;"&gt;这下大家都满足了吧：）&lt;/span&gt;&lt;span style="font-size: 10.5pt;"&gt;&lt;span face="'Times New Roman'" style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/cuipengfei/aggbug/2151375.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cuipengfei/archive/2011/08/23/2151375.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cuipengfei/archive/2011/08/22/2149971.html</id><title type="text">自己动手重新实现LINQ to Objects: 4 - Range</title><summary type="text">本文翻译自JonSkeet的系列博文“Edulinq”。本篇原文地址：http://msmvps.com/blogs/jon_skeet/archive/2010/12/24/reimplementing-linq-to-objects-part-4-range.aspx本篇博文较短，接下来的几篇估计也会比较短。我觉得只有很相似的几个LINQ操作符才适合放到同一篇博文里面，比如Count和LongCount就比较适合放在一起讲。不过我也要采纳读者的意见，如果你喜欢“肥胖”一点的博文的话，请留言说明。本文将要讲解Range操作符。Range操作符是什么？Range只有一种方法签名：publics</summary><published>2011-08-22T14:07:00Z</published><updated>2011-08-22T14:07:00Z</updated><author><name>崔鹏飞</name><uri>http://www.cnblogs.com/cuipengfei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cuipengfei/archive/2011/08/22/2149971.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cuipengfei/archive/2011/08/22/2149971.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="Section0"&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本文翻译自&lt;/span&gt;&lt;span&gt;&lt;a href="http://stackoverflow.com/users/22656/jon-skeet"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;Jon&amp;nbsp;Skeet&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;的系列博文&amp;ldquo;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本篇原文地址：&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2010/12/24/reimplementing-linq-to-objects-part-4-range.aspx"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.5000pt; font-family: 'Times New Roman';"&gt;http://msmvps.com/blogs/jon_skeet/archive/2010/12/24/reimplementing-linq-to-objects-part-4-range.aspx&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本篇博文较短，接下来的几篇估计也会比较短。我觉得只有&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: italic; font-size: 10.5000pt; font-family: '宋体';"&gt;很相似&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;的几个&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;LINQ&lt;span face="宋体" style="font-family: 宋体;"&gt;操作符才适合放到同一篇博文里面，比如&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LongCount&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;就比较适合放在一起讲。不过我也要采纳读者的意见，如果你喜欢&amp;ldquo;肥胖&amp;rdquo;一点的博文的话，请留言说明。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本文将要讲解&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;操作符。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;Range&lt;span face="宋体" style="font-family: 宋体;"&gt;操作符是什么？&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.range.aspx"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;Range&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;只有一种方法签名：&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;&amp;nbsp;Range(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;start,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;count)&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;和&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LINQ&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;中的其他操作符不同，&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;不是扩展方法，它就是一个普通的静态方法。&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;返回一个可枚举的对象，该对象会&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Times New Roman';"&gt;yield&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;返回&amp;ldquo;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;个整数，返回的整数序列从&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;start&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;开始，逐次加一。举例来说，&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Enumerable.Range(6,3)&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;会返回&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;6&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;7&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;8&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;由于&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;不会接受输入序列，所以也就无所谓对输入的流式处理和缓冲了。不过它有以下几点行为：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;参数的校验需要立即执行；参数&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;不可以为负数，也不可以让输出值中包含超出&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Int32&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;范围的值。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;输出值是被延迟输出的。&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的执行效率应该比创建并返回一个&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;长度的数组来得更高。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;我们要如何测试呢？&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;要测试普通的静态方法就给我们带来了一个新的挑战，因为我们要在原版的&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LINQ&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;实现和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现之间做切换。这是由我所使用的命名空间所带来的缺陷，单元测试写在&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq.Tests&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;这个命名空间内，我们的实现写在&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;这个命名空间中。在编译器寻找一个类型的时候，父级命名空间会比其他的通过&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;using&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;引入的命名空间拥有更高的优先级，即使是使用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;using&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;来显式引入一个类型的别名时也是如此。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;我选择的解决方式是用一个&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;using&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;指令来引入一个叫做&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;RangeClass&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的别名。&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;using&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;指令要么指向&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;System.Linq.Enumerable&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;要么指向&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq.Enumerable&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。测试代码中用到&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;时都是这样写：&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;RangeClass.Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。为此我创建了两个项目配置，其中一个定义了叫做&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;NORMAL_LINQ&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的预处理符号，另一个则没有定义任何预处理符号，这样就可以在两种&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LINQ&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;实现之间做切换了。&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;RangeTest.cs&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;中会包含如下的代码：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;#if&amp;nbsp;NORMAL_LINQ&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;using&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;RangeClass&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;System&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;.Linq.Enumerable;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;#else&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;using&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;RangeClass&amp;nbsp;=&amp;nbsp;Edulinq.Enumerable;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;#endif&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;当然了，也有别的办法可以替代以上的方式：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;可以把单元测试代码换到另外一个命名空间中去。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;也可以让项目的引用项依赖于不同的项目配置，用于测试原版&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LINQ&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的项目配置不包含对&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的引用，而用于测试&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的项目配置则不引用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;System.Core&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。这样就可以在&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;NORMAL_LINQ&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的预处理符号下直接使用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;using&amp;nbsp;System.Linq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，并直接使用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Enumerable.Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。测试默认的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LINQ&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;实现时亦是如此。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;我喜欢上面提到的第二种方式，但是那需要手动修改测试工程的工程文件，因为&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Visual&amp;nbsp;Studio&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;没有提供任何根据不同条件引用不同引用项的功能。我以后或许会用到这个方法，欢迎提供建议。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;我们要测试什么呢？&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;Range&lt;span face="宋体" style="font-family: 宋体;"&gt;需要的测试并不多，我只有八个方面需要测试，而且都不怎么很特别：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;一个简单有效的&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;操作应该可以通过&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;AssertSequenceEqual&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的测试。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;起始值应该可以是负数。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;Range(Int32.MinValue,&amp;nbsp;0)&lt;span face="宋体" style="font-family: 宋体;"&gt;会返回一个空序列。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;Range(Int32.MaxValue,&amp;nbsp;1)&lt;span face="宋体" style="font-family: 宋体;"&gt;会返回仅包含&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Int32.MaxValue&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的序列。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;count&lt;span face="宋体" style="font-family: 宋体;"&gt;不可以为负数。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;count&lt;span face="宋体" style="font-family: 宋体;"&gt;可以为&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;0&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;start+count-1&lt;span face="宋体" style="font-family: 宋体;"&gt;不可以超过&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Int32.MaxValue&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;（所以&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range(Int32.MaxValue,&amp;nbsp;2)&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;应该是一个无效操作）。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;start+count-1&lt;span face="宋体" style="font-family: 宋体;"&gt;可以等于&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Int32.MaxValue&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;（所以&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range(Int32.MaxValue,&amp;nbsp;1)&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;应该是一个有效操作）。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;最后两项要分别被几组不同的数据测试，这几组数据是：大的&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;start&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;值和小的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;值，小的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;start&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;值和大的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;值，还有一组是&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;start&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;都相当大。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;请注意我没有做针对于惰性求值的测试，我确实可以测一下返回值是否实现了任何其他的集合接口，不过那会显得有点奇怪。不过我们有一些测试中用到的&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;值非常大，给这么大的集合分配内存几乎肯定要失败。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;开始实现吧！&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;你肯定早就猜到了，我们将会用分隔开的两个方法来实现&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。一个&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;public&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的方法用来立即执行参数校验，还有一个&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;private&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的方法用来做核心部分的工作，其中包含迭代器代码块。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;由于一开始就确定了参数不会超过&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Int32&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的上下限，我们在实现的主体部分就可以随意一点了。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;&amp;nbsp;Range(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;start,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;count)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;if&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(count&amp;nbsp;&amp;lt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;0&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;ArgumentOutOfRangeException(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"count"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;Convert&amp;nbsp;everything&amp;nbsp;to&amp;nbsp;long&amp;nbsp;to&amp;nbsp;avoid&amp;nbsp;overflows.&amp;nbsp;There&amp;nbsp;are&amp;nbsp;other&amp;nbsp;ways&amp;nbsp;of&amp;nbsp;checking&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;for&amp;nbsp;overflow,&amp;nbsp;but&amp;nbsp;this&amp;nbsp;way&amp;nbsp;make&amp;nbsp;the&amp;nbsp;code&amp;nbsp;correct&amp;nbsp;in&amp;nbsp;the&amp;nbsp;most&amp;nbsp;obvious&amp;nbsp;way.&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;if&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;((&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;long&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;)start&amp;nbsp;+&amp;nbsp;(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;long&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;)count&amp;nbsp;-&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;1L&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;.MaxValue)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;ArgumentOutOfRangeException(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"count"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;RangeImpl(start,&amp;nbsp;count);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;private&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;gt;&amp;nbsp;RangeImpl(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;start,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;count)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;for&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;i&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;0&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;count;&amp;nbsp;i++)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;start&amp;nbsp;+&amp;nbsp;i;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;有几点需要说明：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;第二段参数校验的代码检查的是&amp;ldquo;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;start&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;和&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;这二者的合法性，而不是仅仅检查&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;。如果能给&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ArgumentOutOfRangeException&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;（或者是&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;ArgumentException&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;）传入多个参数名就好了，这样就能在异常信息中指出多个参数不合法。话虽这么说，&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;.NET&amp;nbsp;Framework&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现也是只会指出&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;不合法。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;第二段参数校验的代码还可以有很多其他的写法，把所有的操作数都转换成&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;long&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;并不是我们仅有的选择。不过我觉得我选择的这个方法是最简单的，而且也是正确的。采取这种方式，我无须考虑多种情况并保证每一种都是正确的。使用&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Int64&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;可以确保不会有溢出，也无需去考虑&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;checked&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;或&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;unchecked&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;Private&lt;span face="宋体" style="font-family: 宋体;"&gt;方法中的循环也有其他的实现方式，不过我认为我用的这个是最简单的。一种很容易想到的替代方案就是用两个变量，一个是已经返回过的值的个数，另一个是下一个要返回的值，每次循环都把这两个值各自加一。还有一种比较复杂的替代方案是只使用一个循环变量，但是那样的话你就不能写&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;value&amp;nbsp;&amp;lt;&amp;nbsp;start&amp;nbsp;+&amp;nbsp;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;了，因为最后一个返回值有可能是&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Int32.MaxValue&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，你也不能写&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;value&amp;nbsp;&amp;lt;=&amp;nbsp;start&amp;nbsp;+&amp;nbsp;count&amp;nbsp;-&amp;nbsp;1&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;了，因为传入的参数有可能是&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Int32.MaxValue&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;0&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。我不想在代码中处理这么多种临界情况，所以我选择了一个简单正确的方式。如果你真的非常非常注重&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的效率的话，你应该去调查一下其他的可行方案。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;写本文之前，我没有给&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range(Int32.MaxValue,&amp;nbsp;1)&amp;nbsp;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range(Int32.MinValue,&amp;nbsp;0)&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;写出好的单元测试。不过写了上面的那段关于替代性方案的话之后，我找到了合适的测试用例。寻找替代方案可以帮助我想到更多的测试用例，这事儿多有趣。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;结论&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;实现&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Range&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;有助于测试其他的操作符，比如说&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。现在既然我已经实现了一个非扩展方法的&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LINQ&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;操作符了，那无妨把另外两个（&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Empty&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Repeat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;）也实现了。其实我已经实现了&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Empty&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;了，希望今天就能把它整理成文。&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Repeat&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;也不需要多久就能完工，然后我们就可以开始着手于&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LongCount&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;了。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本文中的代码很好的诠释了这种情况：有时，写&amp;ldquo;傻&amp;rdquo;一点的代码会比写短一点，快一点的代码更好，因为它更易于读懂。无疑，以后博文中我还会写更多的&amp;ldquo;傻&amp;rdquo;代码的。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/cuipengfei/aggbug/2149971.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cuipengfei/archive/2011/08/22/2149971.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cuipengfei/archive/2011/08/21/2148737.html</id><title type="text">自己动手重新实现LINQ to Objects: 3 - Select</title><summary type="text">本文翻译自JonSkeet的系列博文“Edulinq”。本篇原文地址：http://msmvps.com/blogs/jon_skeet/archive/2010/12/23/reimplementing-linq-to-objects-part-3-quot-select-quot-and-a-rename.aspx距离上次写完本系列博文的第一篇和第二篇已经有一段日子了，希望接下来的进度会快一些。现在我给本项目在GoogleCode上建立了源码管理，现在就无需每篇博文包含一个zip文件了。创建项目时，我给它取了个显而易见的名字，叫做Edulinq。我修改了代码中的命名空间，而且现在这一系列博</summary><published>2011-08-21T15:22:00Z</published><updated>2011-08-21T15:22:00Z</updated><author><name>崔鹏飞</name><uri>http://www.cnblogs.com/cuipengfei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cuipengfei/archive/2011/08/21/2148737.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cuipengfei/archive/2011/08/21/2148737.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;div class="Section0"&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本文翻译自&lt;/span&gt;&lt;span&gt;&lt;a href="http://stackoverflow.com/users/22656/jon-skeet"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;Jon&amp;nbsp;Skeet&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;的系列博文&amp;ldquo;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;本篇原文地址：&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2010/12/23/reimplementing-linq-to-objects-part-3-quot-select-quot-and-a-rename.aspx"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.5000pt; font-family: 'Times New Roman';"&gt;http://msmvps.com/blogs/jon_skeet/archive/2010/12/23/reimplementing-linq-to-objects-part-3-quot-select-quot-and-a-rename.aspx&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;距离上次写完本系列博文的&lt;/span&gt;&lt;span&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2010/09/03/reimplementing-linq-to-objects-part-1-introduction.aspx"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;第一篇&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;和&lt;/span&gt;&lt;span&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2010/09/03/reimplementing-linq-to-objects-part-2-quot-where-quot.aspx"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;第二篇&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;已经有一段日子了，希望接下来的进度会快一些。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;现在我给本项目在&lt;/span&gt;&lt;span&gt;&lt;a href="http://edulinq.googlecode.com/"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;Google&amp;nbsp;Code&lt;span face="宋体" style="font-family: 宋体;"&gt;上建立了源码管理&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;，现在就无需每篇博文包含一个&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;zip&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;文件了。创建项目时，我给它取了个显而易见的名字，叫做&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。我修改了代码中的命名空间，而且现在&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/tags/Edulinq/default.aspx"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;这一系列博文的&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;tag&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;也修改为了&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Edulinq&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;了。好了，闲话少叙&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;...&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;我们来开始重新实现&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;LINQ&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;吧，这次要实现&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;操作符。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;Select&lt;span face="宋体" style="font-family: 宋体;"&gt;操作符是什么？&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;和&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Where&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;类似，&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb357126.aspx"&gt;&lt;span class="15" style="mso-spacerun: 'yes'; color: #0000ff; text-decoration: underline; font-size: 10.0000pt; font-family: '宋体';"&gt;Select&lt;span face="宋体" style="font-family: 宋体;"&gt;也有两个重载&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;：&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: '宋体';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: '宋体';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;Select&amp;lt;TSource,&amp;nbsp;TResult&amp;gt;(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: '宋体';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;TResult&amp;gt;&amp;nbsp;selector)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: '宋体';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: '宋体';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;Select&amp;lt;TSource,&amp;nbsp;TResult&amp;gt;(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: '宋体';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: '宋体';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;,&amp;nbsp;TResult&amp;gt;&amp;nbsp;selector)&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;其第二个重载让投影操作可以访问到序列元素的&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;index&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;先说简单的东西：&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;方法把一个序列&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: italic; font-size: 10.5000pt; font-family: '宋体';"&gt;投影&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;成为另一个序列：&amp;ldquo;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;selector&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;这个作为参数的委托会被依次应用到输入序列中的每一个元素上，并每次&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;yield&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;返回一个输出元素。&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的行为和&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Where&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;很类似（实在是太类似了，以至于下面一段文字都是从上一篇文章中复制过来的，只是稍加修改）：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;Select&lt;span face="宋体" style="font-family: 宋体;"&gt;不会对输入序列做任何修改。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;Select&lt;span face="宋体" style="font-family: 宋体;"&gt;是延迟执行的&amp;nbsp;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;-&amp;nbsp;&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;在你开始读取输出序列中的元素之前，&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;不会去输入序列中取元素。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;不过也有一点不是延迟执行的，它会立即检查参数是否为&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;null&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;它以流式处理结果：它每次只处理一个结果元素。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;你每在输出序列上迭代一次，&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;方法就会在输入序列上迭代一次，这二者是严格对应的。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;每次&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;yield&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;返回结果值的时候，&amp;ldquo;&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;selector&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;这个委托就会被调用一次。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;如果输出序列的迭代器被&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Dispose&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;掉的话，对应的输入序列的迭代器也会被&lt;/span&gt;&lt;span face="Times New Roman" style="font-family: 'Times New Roman';"&gt;Dispose&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;掉。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: normal; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;我们要测试什么？&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;对&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的测试和对&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Where&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的测试也是很类似的，之前我们是针对&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Where&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的过滤功能来做测试，现在我们是针对&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的投影功能来做测试。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;有几个测试比较有趣。首先，你会发现&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;方法是泛型的，而且有两个泛型参数，分别是&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;TSource&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;TResult&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;。虽然这两个参数的含义不言自明，不过还是得写一个单元测试来测一下&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;TSource&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;TResult&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;分别为不同类型的情况，比如说把&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;转换成&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;string&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的情况。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;[Test]&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;void&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;SimpleProjectionToDifferentType()&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;[]&amp;nbsp;source&amp;nbsp;=&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;1&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;5&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;2&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;};&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;result&amp;nbsp;=&amp;nbsp;source.Select(x&amp;nbsp;=&amp;gt;&amp;nbsp;x.ToString());&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result.AssertSequenceEqual(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"1"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"5"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"2"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;然后我们看另一个测试，这个测试给我们展示了使用&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;LINQ&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;有可能会遇到的奇怪的副作用。其实我们本可以在&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Where&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的单元测试中做这个例子的，不过针对&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;做起来更清晰一些：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;[Test]&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;void&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;SideEffectsInProjection()&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;[]&amp;nbsp;source&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;[&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;3&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;];&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #008040; font-style: italic; font-size: 10.5000pt; font-family: 'Courier New';"&gt;//&amp;nbsp;Actual&amp;nbsp;values&amp;nbsp;won't&amp;nbsp;be&amp;nbsp;relevant&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;count&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;0&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;query&amp;nbsp;=&amp;nbsp;source.Select(x&amp;nbsp;=&amp;gt;&amp;nbsp;count++);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;query.AssertSequenceEqual(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;0&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;1&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;2&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;query.AssertSequenceEqual(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;3&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;4&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;5&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;10&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;query.AssertSequenceEqual(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;10&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;11&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;12&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;请注意我们只调用了&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;一次，但是对&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;方法返回值的多次迭代结果都不同，这是因为&amp;ldquo;&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;count&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;这个变量的值被保留住了并在每一次的投影过程中都会被修改。希望您不要写出这种代码。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;再然后，我们可以写一些同时包含&amp;ldquo;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;和&amp;ldquo;&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;where&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;&amp;rdquo;的查询表达式：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;[Test]&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;void&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;WhereAndSelect()&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;int&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;[]&amp;nbsp;source&amp;nbsp;=&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;1&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;3&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;4&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;2&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;8&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;1&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;};&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;result&amp;nbsp;=&amp;nbsp;from&amp;nbsp;x&amp;nbsp;in&amp;nbsp;source&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;where&amp;nbsp;x&amp;nbsp;&amp;lt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;4&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;select&amp;nbsp;x&amp;nbsp;*&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;2&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result.AssertSequenceEqual(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;2&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;6&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;4&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;2&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;如果你用过&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;LINQ&amp;nbsp;to&amp;nbsp;Objects&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的话，那么上面这些东西对你来说应该是很熟悉很亲切的，没有什么令人惊讶的。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;来动手实现吧！&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;我们实现&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的方式和实现&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Where&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的方式差不多。我只是把&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Where&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现的代码复制过来，稍加修改，这二者真的就是如此的相似。详细说来就是：&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;我们利用迭代器代码块来轻松实现序列的返回。&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;要用到迭代器代码块就意味着必须要把参数校验的代码和核心实现代码分离开。（我写完上一篇博文之后了解到&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;VB11&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;中将会有匿名迭代器，匿名迭代器可以解决这个问题。哎。羡慕&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;VB&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;用户的感觉怪怪的，但是我会学着接受现实的。）&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-left: 21.0000pt; text-indent: -21.0000pt; margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Wingdings';"&gt;l&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;我们在迭代器代码块中使用&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;foreach&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;，这样就可以保证在输出序列的迭代器被&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Dispose&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;时或者输入序列的元素被迭代完时，输入序列的迭代器可以被妥当的&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Dispose&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;掉。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;由于&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现和&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Where&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的实现实在是太类似了，下面我直接给出代码。&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;方法的重载（含有&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;index&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;的那一个）的实现代码就不展示了，因为它和下面的代码差别实在太小了。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;public&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;Select&amp;lt;TSource,&amp;nbsp;TResult&amp;gt;(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;TResult&amp;gt;&amp;nbsp;selector)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;if&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(source&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;ArgumentNullException(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"source"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;if&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;(selector&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;new&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;ArgumentNullException(&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #ff00ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;"selector"&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;SelectImpl(source,&amp;nbsp;selector);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;private&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;static&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TResult&amp;gt;&amp;nbsp;SelectImpl&amp;lt;TSource,&amp;nbsp;TResult&amp;gt;(&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;this&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;IEnumerable&amp;lt;TSource&amp;gt;&amp;nbsp;source,&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&amp;lt;TSource,&amp;nbsp;TResult&amp;gt;&amp;nbsp;selector)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&amp;nbsp;(TSource&amp;nbsp;item&amp;nbsp;in&amp;nbsp;source)&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; color: #0000ff; font-size: 10.5000pt; font-family: 'Courier New';"&gt;return&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;selector(item);&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;}&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;很简单，对吧？真正用来实现功能的代码还没有参数校验的代码长呢。&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;结论&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-weight: bold; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;虽然说我不想让我的读者感到无聊（你们中的有些人&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-style: italic; font-size: 10.5000pt; font-family: '宋体';"&gt;可能&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;会感到惊讶），但是我还是得承认本篇文章颇有些无趣。我重复的强调&amp;ldquo;和&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Where&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;很类似&amp;rdquo;，强调了那么多次，搞得都有点乏味了，不过这样才足以说明实现&lt;/span&gt;&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;Select&lt;/span&gt;&lt;span face="宋体" style="font-family: 宋体;"&gt;并没有你可能想象的那么复杂。&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: '宋体';"&gt;下次（我希望就在几天之内）我会写点不一样的东西。我还不确定下次要写哪个方法，待选的方法还有很多&lt;span face="Courier New" style="font-family: 'Courier New';"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-spacerun: 'yes'; font-size: 10.5000pt; font-family: 'Courier New';"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/cuipengfei/aggbug/2148737.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cuipengfei/archive/2011/08/21/2148737.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
