<p>Matt提到了查询表达式。顺便说一句,这些通常可用于LINQ,而不仅仅是LINQ to对象。(例如,应用于linqtosqldatacontext的同一查询将在数据库上执行筛选和投影。)</p>
<p>C#3中的查询表达式只是编写普通C#代码时的语法糖,尽管查询表达式通常最终调用<a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" rel="nofollow noreferrer">extension methods</a>。(它们不必这样做,编译器也不在乎,但它们通常会这样做。)对于在C查询表达式中不可用但由方法调用支持的集合,可以做很多事情,因此值得注意这两种语法。例如,Matt的查询表达式:</p>
<pre><code>List<Foo> fooList = new List<Foo>();
IEnumerable<string> extract = from foo in fooList where foo.Bar > 10 select foo.Name.ToUpper();
</code></pre>
<p>“预处理”为:</p>
<pre><code>List<Foo> fooList = new List<Foo>();
IEnumerable<string> extract = fooList.Where(foo => foo.Bar > 10)
.Select(foo => foo.Name.ToUpper());
</code></pre>
<p>如果要(比方说)基于原始集合中值的索引进行筛选,可以使用通过查询表达式不可用的<a href="http://msdn.microsoft.com/en-us/library/bb549418.aspx" rel="nofollow noreferrer">appropriate overload of Where</a>:</p>
<pre><code>List<Foo> fooList = new List<Foo>();
IEnumerable<string> extract = fooList.Where((foo, index) => foo.Bar > 10 + index)
.Select(foo => foo.Name.ToUpper());
</code></pre>
<p>或者可以找到与条件匹配的最长名称的长度:</p>
<pre><code>List<Foo> fooList = new List<Foo>();
int longestName = fooList.Where((foo, index) => foo.Bar > 10 + index)
.Select(foo => foo.Name)
.Max();
</code></pre>
<p>(您不需要在单独的方法中使用</em>来执行projection和max——还有一个<code>Max</code>重载也需要一个projection。)</p>
<p>我的观点是,使用扩展方法可以非常容易地构建复杂的查询。</p>
<p>您还提到了Python生成器-C以<a href="https://stackoverflow.com/questions/317462/some-help-understanding-yield">iterator blocks</a>的形式提供了它。实际上,在实现类似LINQ的操作符时,这些方法非常有用。(因为大多数LINQ to对象都是基于扩展方法的,所以您可以添加自己的操作符,这些操作符看起来像LINQ的“原生”操作符——尽管您自己不能更改查询表达式语法。)</p>