﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-Rudo</title><link>http://www.cnblogs.com/BoardPung/</link><description>Develop simple and delightful technologies</description><language>zh-cn</language><lastBuildDate>Sat, 06 Sep 2008 02:42:06 GMT</lastBuildDate><pubDate>Sat, 06 Sep 2008 02:42:06 GMT</pubDate><ttl>60</ttl><item><title>.Net专题(C# 中的委托和事件) - Part.1 </title><link>http://www.cnblogs.com/BoardPung/archive/2007/09/28/909049.html</link><dc:creator>BoardPung</dc:creator><author>BoardPung</author><pubDate>Fri, 28 Sep 2007 03:02:00 GMT</pubDate><guid>http://www.cnblogs.com/BoardPung/archive/2007/09/28/909049.html</guid><wfw:comment>http://www.cnblogs.com/BoardPung/comments/909049.html</wfw:comment><comments>http://www.cnblogs.com/BoardPung/archive/2007/09/28/909049.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/BoardPung/comments/commentRss/909049.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/BoardPung/services/trackbacks/909049.html</trackback:ping><description><![CDATA[摘要: 转自：.Net专题(C# 中的委托和事件) - Part.1 PDF版浏览：http://www.cnblogs.com/Files/JimmyZhang/Delegates-and-Events-In-CSharp.pdf引言委托 和 事件在 .Net Framework中的应用非常广泛，然而，较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿，过了这个槛的人，觉得真&nbsp;&nbsp;<a href='http://www.cnblogs.com/BoardPung/archive/2007/09/28/909049.html'>阅读全文</a><img src ="http://www.cnblogs.com/BoardPung/aggbug/909049.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42116/" target="_blank">[新闻]消息称MySQL创始人已向Sun提交辞呈</a>]]></description></item><item><title>新Orcas语言特性：查询句法 </title><link>http://www.cnblogs.com/BoardPung/archive/2007/08/22/864912.html</link><dc:creator>BoardPung</dc:creator><author>BoardPung</author><pubDate>Wed, 22 Aug 2007 02:08:00 GMT</pubDate><guid>http://www.cnblogs.com/BoardPung/archive/2007/08/22/864912.html</guid><wfw:comment>http://www.cnblogs.com/BoardPung/comments/864912.html</wfw:comment><comments>http://www.cnblogs.com/BoardPung/archive/2007/08/22/864912.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/BoardPung/comments/commentRss/864912.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/BoardPung/services/trackbacks/864912.html</trackback:ping><description><![CDATA[<h2><a id="viewpost_ascx_TitleUrl" href="http://blog.joycode.com/scottgu/archive/2007/04/24/101654.aspx">新Orcas语言特性：查询句法</a> </h2>
<p>【原文地址】<a title="新Orcas语言特性：查询句法" href="http://weblogs.asp.net/scottgu/archive/2007/04/21/new-orcas-language-feature-query-syntax.aspx">New "Orcas" Language Feature: Query Syntax</a> <br />
【原文发表日期】 Saturday, April 21, 2007 2:12 </p>
<p>上个月我开始了一个贴子系列，讨论作为Visual Studio和.NET框架Orcas版本一部分发布的一些新的VB和C#语言特性。下面是该系列的前三篇贴子的链接：
<ul>
    <li><a href="http://blog.joycode.com/scottgu/archive/2007/03/11/95954.aspx" target="_blank">自动属性，对象初始化器，和集合初始化器</a>
    <li><a href="http://blog.joycode.com/scottgu/archive/2007/04/07/100611.aspx" target="_blank">扩展方法</a>
    <li><a href="http://blog.joycode.com/scottgu/archive/2007/04/09/100744.aspx" target="_blank">Lambda表达式</a></li>
</ul>
<p>今天的贴子要讨论另一个基础性的新语言特性：<em>查询句法(Query Syntax)</em>。 </p>
<h3><u>什么是查询句法(Query Syntax)？</u></h3>
<p>查询句法是使用标准的LINQ查询运算符来表达查询时一个方便的声明式简化写法。该句法能在代码里表达查询时增进可读性和简洁性，读起来容易，也容易让人写对。Visual Studio 对查询句法提供了完整的intellisense和编译时检查支持。</p>
<p>在底下，C#和VB编译器则把查询句法的表达式翻译成明确的方法调用代码，这样的代码利用了Orcas中的新的<a href="http://blog.joycode.com/scottgu/archive/2007/04/07/100611.aspx" target="_blank">扩展方法</a>和<a href="http://blog.joycode.com/scottgu/archive/2007/04/09/100744.aspx" target="_blank">Lambda表达式</a>语言特性。 </p>
<h3><u>查询句法的例子：</u></h3>
<p>在我以前的语言系列贴子里，我示范了你可以象下面这样声明一个Person类：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step1.jpg"  alt="" /> </p>
<p>&nbsp;</p>
<p>然后我们可以使用下面这样的代码，用一些个人信息来生成一个List&lt;Person&gt;集合实例，然后使用<em>查询句法</em>来对该集合做一个LINQ查询，只取出那些姓（last name）的首字母为G的人，按名字（first name）来排序（升序）： </p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step2.jpg"  alt="" /> </p>
<p>上面查询句法的表达式在语意上与下面明确使用LINQ<a href="http://blog.joycode.com/scottgu/archive/2007/04/07/100611.aspx" target="_blank">扩展方法</a>和<a href="http://blog.joycode.com/scottgu/archive/2007/04/09/100744.aspx" target="_blank">Lambda表达式</a>的代码是等同的： </p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step3.jpg"  alt="" /> </p>
<p>使用查询句法方法的好处是，结果会是稍微容易读写些，这在表达式变得更繁复时尤其如此。 </p>
<h3><u>查询句法 - 理解from和select子句：</u></h3>
<p>在C#中，每个查询表达式的句法从from子句开始，以select或group子句结束。from子句表示你要查询什么数据。select子句则表示你要返回什么数据，且应该以什么构形返回。</p>
<p>譬如，让我们再来看一下我们对List&lt;Person&gt;集合的查询：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step18.jpg"  alt="" /> </p>
<p>在上面的代码片段里，"from p in people"表示了我要对"people" 这个集合做一个LINQ查询，我将用参数"p"代表我正查询的输入序列的每个项。我们将参数命名为"p" 这个事实是无关紧要的，我完全可以很容易地将其命名为"o", "x", "person"或我想要的任何名字。 </p>
<p>在上面的代码片段里，语句结尾的"select p"子句表示，作为查询的结果，我要返回一个Person对象的IEnumerable序列。这是因为"people"集合包含了Person类型的对象，而参数p则代表了输入序列中的Person对象。因此，该查询句法表达式的结果数据类型是IEnumerable&lt;Person&gt;。 </p>
<p>假如不是返回Person对象，我想返回该集合中的人的名字，我可以把查询改写成这样：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step4.jpg"  alt="" /> </p>
<p>注意上面我不再说"select p"，而是说"select p.FirstName"。这表示我不想返回一串Person对象，而是想返回一串字符串，由Person对象的FirstName属性（该属性是个字符串）填充而来。 因此，该查询句法表达式的结果类型是 IEnumerable&lt;string&gt;。</p>
<p><u>针对数据库的查询句法的例子</u></p>
<p>LINQ的妙处在于，我可以针对任何数据类型使用完全一样的查询句法。譬如，我可以使用Orcas提供的新LINQ到SQL对象关系映射器支持，对SQL服务器的Northwind数据库进行建模，生成下面这些类（请<a href="http://blog.joycode.com/scottgu/archive/2007/01/30/92804.aspx" target="_blank">观看我这里的录像</a>来学习该如何实现）： </p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step5.jpg"  alt="" /> </p>
<p>在上面定义好类模型之后（以及它与数据库间的映射关系），然后我就可以写个查询句法的表达式取出那些单价大于99元的产品：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step6.jpg"  alt="" /> </p>
<p>在上面的代码片段里，我表示我要对NorthwindDataContext类的Products表进行一个LINQ查询，NorthwindDataContext类是由Visual Studio Orcas的ORM设计器生成的。"select p"表示我要返回匹配我的查询的一串Product对象，因此，该查询句法表达式的结果数据类型是IEnumerable&lt;Product&gt;。 </p>
<p>就象前面List&lt;Person&gt;查询句法的例子一样，C# 编译器会把我们的声明式查询句法翻译成明确的扩展方法调用（使用Lambda表达式作为参数）。在上面的LINQ到SQL的例子的情形下，这些Lambda表达式会被转化成SQL命令，然后在SQL服务器上做运算（这样，只有那些匹配查询条件的Product记录行会返回到我们的应用中）。促成这个Lambda-&gt;SQL 转化的机制的细节可见于我的<a href="http://blog.joycode.com/scottgu/archive/2007/04/09/100744.aspx" target="_blank">Lambda表达式博客贴子</a>的"Lambda表达式树"部分。 </p>
<h3><u>查询句法 - 理解where和orderby子句：</u></h3>
<p>在一个查询句法表达式开头的"from" 子句和结尾的"select"子句之间，你可以使用最常见的LINQ查询运算符来过滤和转换你在查询的数据。两个最常用的子句是"where"和"orderby"。这两个子句处理对结果集的过滤和排序。 </p>
<p>譬如，要从Northwind数据库里返回按字母降序排列的分类名称列表，过滤条件是只包括那些含有5个以上产品的分类，我们可以编写下面这样的查询句法来用LINQ到SQL对我们的数据库做查询：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step7.jpg"  alt="" /> </p>
<p>在上面的表达式里，我们加了 "where c.Products.Count &gt; 5" 子句来表示我们只要那些含有5个以上产品的分类。这利用了数据库中产品和分类间的LINQ到SQL的ORM映射的关联。在上面的表达式中，我也加了"order by c.CategoryName descending"子句来表示我要将结果集按名称降序排列。</p>
<p>LINQ到SQL然后就会在使用这个表达式查询数据库时，生成下列SQL：</p>
<blockquote>
<p>SELECT [t0].[CategoryName] FROM [dbo].[Categories] AS [t0]<br />
WHERE ((<br />
&nbsp;&nbsp;&nbsp; SELECT COUNT(*)<br />
&nbsp;&nbsp;&nbsp; FROM [dbo].[Products] AS [t1]<br />
&nbsp;&nbsp;&nbsp; WHERE [t1].[CategoryID] = [t0].[CategoryID]<br />
)) &gt; 5<br />
ORDER BY [t0].[CategoryName] DESC</p>
</blockquote>
<p>注意，LINQ到SQL很聪明，只返回了我们所需的单个字段（分类名称), 而且它是在数据库层做了所有的过滤和排序，使得该查询效率非常高。</p>
<h3><u>查询句法 - 用投影(Projection)来转换数据</u></h3>
<p>先前我指出的一个要点是，"select" 子句表示了你要返回的数据，<em>以及这个数据的构形是什么</em>。 </p>
<p>譬如，假如你有个象下面这样的"select p" 子句，这里p的类型是Person，然后，它就会返回一串Person对象：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step2.jpg"  alt="" /> </p>
<p>LINQ和查询句法提供的一个非常强大的功能是允许你定义跟被查询的数据分开的新的类型，然后用新的类型来控制查询返回的数据的形状和结构。</p>
<p>譬如，假设我们定义了一个新的AlternatePerson类，内含一个FullName属性，而不是我们原先的Person类内的分开的FirstName和LastName属性：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step8.jpg"  alt="" /> </p>
<p>然后我就可以使用下面的LINQ查询句法来查询我原先的List&lt;Person&gt;集合，用下面的查询句法将结果转换成一串AlternatePerson对象：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step9.jpg"  alt="" /> </p>
<p>注意看，我们是如何在上面的表达式里的"select"子句里，使用<a href="http://blog.joycode.com/scottgu/archive/2007/03/11/95954.aspx" target="_blank">我的语言系列的第一个贴子</a>里讨论过的新的<a href="http://blog.joycode.com/scottgu/archive/2007/03/11/95954.aspx" target="_blank">对象初始化器句法</a>来创建新的AlternatePerson实例，同时设置它的属性的。也注意我是如何连接我们原先Person类的FirstName和LastName属性，然后将其赋值给FullName属性的。 </p>
<p><u>对数据库使用查询句法投影</u></p>
<p>这个投影特性在操作从象数据库这样一个远程数据提供器那里取回的数据时，会变得难以置信地有用，因为它提供给我们一个优雅的方式，来表示我们的ORM应该从数据库实际取回哪些数据字段。</p>
<p>譬如，假设我用了LINQ到SQL的ORM提供器对Northwind数据库建模，生成下面这些类：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step10.jpg"  alt="" /> </p>
<p>通过编写下面这个LINQ查询，我告诉LINQ到SQL我要返回一串Product对象：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step11.jpg"  alt="" /> </p>
<p>填充Product类所需的所有字段都将作为上面查询的一部分从数据库中返回，由LINQ到SQL ORM执行的raw SQL看上去象下面这样：</p>
<blockquote>
<p>SELECT&nbsp;[t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]<br />
FROM [dbo].[Products] AS [t0]<br />
WHERE [t0].[UnitPrice] &gt; 99 </p>
</blockquote>
<p>在一些场景下，我不需要也不用所有这些字段，我可以定义一个下面这样的新的MyProduct类，只拥有Product类具有的部分属性，以及一个Product类并不具有的额外属性，TotalRevenue （注： 对那些不熟悉C#的，Decimal?句法表示我们的UnitPrice属性是个nullable值）： </p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step12.jpg"  alt="" />&nbsp;</p>
<p>然后我就可以使用下面这个查询，使用查询句法的投影功能来构造我要从数据库返回的数据的形状：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step13.jpg"  alt="" /> </p>
<p>这表明，不是返回一串Product对象，我要MyProduct对象，我只要其中三个属性被赋值，LINQ到SQL就会很聪明地调整要执行的raw SQL语句，从数据库只返回那三个需要的产品字段：</p>
<blockquote>
<p>SELECT [t0].[ProductID], [t0].[ProductName], [t0].[UnitPrice]<br />
FROM [dbo].[Products] AS [t0]<br />
WHERE [t0].[UnitPrice] &gt; 99 </p>
</blockquote>
<p>为炫耀起见，我也可以填充MyProduct类的第四个属性，即TotalRevenue属性。我要这个值等于我们产品目前的销售额的总量。这个值在Northwind数据库中并没有作为一个预先算好的字段而存在。而是，你需要在Products表和Order Details表间做一个关联，然后计算出一个给定产品对应的所有的Order Detail 行的总量。</p>
<p>非常酷的是，我可以在Product类的OrderDetails关联上使用LINQ的 Sum 这个<a href="http://blog.joycode.com/scottgu/archive/2007/04/07/100611.aspx" target="_blank">扩展方法</a>，编写一个作为我的查询句法投影一部分的乘法<a href="http://blog.joycode.com/scottgu/archive/2007/04/09/100744.aspx" target="_blank">Lambda表达式</a>，来计算这个值：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step14.jpg"  alt="" /> </p>
<p>LINQ到SQL就会非常聪明地使用下面这个SQL在SQL数据库里做运算：</p>
<blockquote>
<p>SELECT [t0].[ProductID], [t0].[ProductName], [t0].[UnitPrice], (<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT SUM([t2].[value])<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM (<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT [t1].[UnitPrice] * (CONVERT(Decimal(29,4),[t1].[Quantity])) AS [value], [t1].[ProductID]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FROM [dbo].[Order Details] AS [t1]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ) AS [t2]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE [t2].[ProductID] = [t0].[ProductID]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ) AS [value]<br />
FROM [dbo].[Products] AS [t0]<br />
WHERE [t0].[UnitPrice] &gt; 99</p>
</blockquote>
<h3><u>查询句法 - 理解延迟执行(Deferred Execution)和使用ToList() 和ToArray() </u></h3>
<p>在默认情形下，查询句法表达式的结果的类型是IEnumerable&lt;T&gt;。在上面的例子里，你会注意到所有的查询句法赋值是给IEnumerable&lt;Product&gt;, IEnumerable&lt;string&gt;, IEnumerable&lt;Person&gt;, IEnumerable&lt;AlternatePerson&gt;, 和 IEnumerable&lt;MyProduct&gt; 变量的。 </p>
<p>IEnumerable&lt;T&gt;接口的一个很好的特征是，实现它们的对象可以把实际的查询运算延迟到开发人员第一次试图对返回值进行迭代(这是通过使用最早在VS 2005中C# 2.0 中引进的yield构造来达成的)时才进行。LINQ和查询句法表达式利用了这个特性，将查询的实际运算延迟到了你第一次对返回值进行循环时才进行。假如你对IEnumerable&lt;T&gt;的结果从不进行迭代的话，那么查询根本就不会执行。 </p>
<p>譬如，考虑下面这个LINQ到SQL的例子：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step15.jpg"  alt="" /> </p>
<p><u>不是</u>在查询句法表达式声明的时候，而是在我们第一次试图对结果进行循环（上面红箭头标志的地方），才会去访问数据库以及取出填充Category对象所需的值。</p>
<p>这个延迟运算的行为结果变得非常有用，因为它促成了一些把多个LINQ查询和表达式链在一起的强有力的组合场景。譬如，我们可以把一个表达式的结果喂给另一个表达式，然后通过延迟运算，允许象LINQ 到SQL这样的ORM根据整个表达式树来优化raw SQL。我将在以后的一个博客贴子里对这样的场景做示范说明。</p>
<p><u>如何立刻对查询句法表达式做运算</u></p>
<p>如果你不要延迟查询运算，而是要对它们立刻就执行运算，你可以使用内置的ToList() 和ToArray() 运算符来返回一个包括了结果集的List&lt;T&gt;或者数组。 </p>
<p>譬如，要返回一个基于范型的 List&lt;T&gt; 集合的话：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step16.jpg"  alt="" /> </p>
<p>要返回一个数组的话：</p>
<p><img src="http://www.scottgu.com/blogposts/querysyntax/step17.jpg"  alt="" /> </p>
<p>在上面两种情形下，会立刻访问数据库，填充Category对象。 </p>
<h3><u>结语</u></h3>
<p>查询句法在使用标准的LINQ查询运算符来表达查询时，提供了非常方便的声明式简化写法。它提供的句法可读性非常高，可以针对任何类型的数据（内存中的集合，数组，XML内容，以及象数据库这样的远程数据提供器，web服务等等）进行查询。一旦你熟悉这个句法后，你可以在任何地方应用这个知识。</p>
<p>在不远的将来，我将结束本语言系列的最后一部分，该部分将讨论新的匿名类型特性。然后我将转而讨论在实际应用中使用所有这些语言特性的一些非常实用的例子（特别是针对数据库和XML文件使用LINQ的例子）。</p>
<p>希望本文对你有所帮助，</p>
<p>Scott</p>
<div class="postfoot">
<div>标签： <a href="http://weblogs.asp.net/scottgu/archive/tags/ASP.NET/default.aspx" rel="tag">ASP.NET</a>, <a href="http://weblogs.asp.net/scottgu/archive/tags/.NET/default.aspx" rel="tag">.NET</a>, <a href="http://weblogs.asp.net/scottgu/archive/tags/LINQ/default.aspx" rel="tag">LINQ</a>, <a href="http://weblogs.asp.net/scottgu/archive/tags/Data/default.aspx" rel="tag">Data</a></div>
</div>
<img src ="http://www.cnblogs.com/BoardPung/aggbug/864912.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42115/" target="_blank">[新闻]谷歌Chrome浏览器即将更换LOGO颜色？</a>]]></description></item><item><title>Orcas中C#语言的新特性：自动属性，对象初始化器，和集合初始化器 </title><link>http://www.cnblogs.com/BoardPung/archive/2007/08/22/864887.html</link><dc:creator>BoardPung</dc:creator><author>BoardPung</author><pubDate>Wed, 22 Aug 2007 01:52:00 GMT</pubDate><guid>http://www.cnblogs.com/BoardPung/archive/2007/08/22/864887.html</guid><wfw:comment>http://www.cnblogs.com/BoardPung/comments/864887.html</wfw:comment><comments>http://www.cnblogs.com/BoardPung/archive/2007/08/22/864887.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/BoardPung/comments/commentRss/864887.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/BoardPung/services/trackbacks/864887.html</trackback:ping><description><![CDATA[<p>【原文地址】<a title="Orcas中C#语言的新特性：自动属性，对象初始化器，和集合初始化器" href="http://weblogs.asp.net/scottgu/archive/2007/03/08/new-c-orcas-language-features-automatic-properties-object-initializers-and-collection-initializers.aspx">New C# "Orcas" Language Features: Automatic Properties, Object Initializers, and Collection Initializers</a><br />
【原文发表日期】 Thursday, March 08, 2007 11:01 PM </p>
<p>上个星期，我们发布了我们的Visual Studio和.NET框架Orcas版<a href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx" target="_blank">三月份的CTP</a>，这是个谁都可以下的免费下载，同时提供VPC镜像(允许你在一个虚拟机里运行它)以及单独的安装文件(注：如果你在运行Vista的话，你要确认你只使用VPC版本)。你可以在<a href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx" target="_blank">这里</a>下载。 </p>
<p>几个星期前，我曾在博客上讨论过Orcas中针对ASP.NET开发人员的<a href="http://blog.joycode.com/scottgu/archive/2007/02/10/93432.aspx" target="_blank">一些重大的改进</a>。如果你还没有读过这个贴子的话，我强烈建议你<a href="http://blog.joycode.com/scottgu/archive/2007/02/10/93432.aspx" target="_blank">在这里读一下</a>。我认为你会非常喜欢该帖子讨论的新特性的。 </p>
<p>除了那些框架和工具类的精彩新特性外，我认为开发人员(包括所有的.NET应用类型的开发人员)会非常喜爱Orcas的一件事情是，VB和C#将包含一些新语言特性和改进。这些语言改动将以既微妙又深刻的方式改进我们的开发体验，势将改进效率，减小我们需要键入的代码量。 </p>
<p>在下几个星期里，我将试着在博客里讨论几个这些语言的改进之处，示范如何把它们使用在一起，来产生一些非常强有力的结果。</p>
<p><strong>新的C#语言特性：自动属性(Automatic Properties)</strong></p>
<p>如果你现在是C#开发人员的话，你大概非常习惯编写象下面这个代码片段一样带有基本属性的类型：</p>
<p>
<div style="border-right: white 2px ridge; padding-right: 10px; border-top: white 2px ridge; padding-left: 10px; font-size: 10pt; padding-bottom: 10px; margin: 10px; border-left: white 2px ridge; padding-top: 10px; border-bottom: white 2px ridge; font-family: courier new; background-color: #eeeeee; word-wrap: break-word">&nbsp;&nbsp;&nbsp;&nbsp;<font color="blue">public&nbsp;class&nbsp;</font><font color="black">Person&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">private&nbsp;string&nbsp;</font><font color="black">_firstName</font><font color="blue">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;string&nbsp;</font><font color="black">_lastName</font><font color="blue">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;int&nbsp;</font><font color="black">_age</font><font color="blue">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;</font><font color="black">FirstName&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">get&nbsp;</font><font color="black">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">return&nbsp;</font><font color="black">_firstName</font><font color="blue">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="black">}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">set&nbsp;</font><font color="black">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_firstName&nbsp;</font><font color="blue">=&nbsp;value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="black">}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">public&nbsp;string&nbsp;</font><font color="black">LastName&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">get&nbsp;</font><font color="black">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">return&nbsp;</font><font color="black">_lastName</font><font color="blue">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="black">}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">set&nbsp;</font><font color="black">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_lastName&nbsp;</font><font color="blue">=&nbsp;value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="black">}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">public&nbsp;int&nbsp;</font><font color="black">Age&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">get&nbsp;</font><font color="black">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">return&nbsp;</font><font color="black">_age</font><font color="blue">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="black">}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">set&nbsp;</font><font color="black">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_age&nbsp;</font><font color="blue">=&nbsp;value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="black">}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</font> </div>
<p>&nbsp;</p>
<p>注意，我们在属性的geter/setter中实际上并没有添加什么逻辑，我们只是将get/set实施到了一个成员变量。我们不禁要问这样一个问题：为什么不直接使用成员变量而使用属性呢？这是因为，向外面呈现公开的成员变量有很多不好的地方。二个最大的问题是：1) 你无法轻易地对成员变量做数据绑定，2) 如果你从类中向外呈现成员变量的话，之后，你不重新编译那些引用老的类的任何程序集，就无法将它们改成属性(譬如，要添加验证逻辑到setter里)。 </p>
<p>Orcas中发布的新C#编译器通过一个叫&#8220;自动属性(automatic properties)&#8221;的语言特性提供了一个优雅的方式来使得你的编码更加简洁，同时还保持属性的灵活性。自动属性允许你避免手工声明一个私有成员变量以及编写get/set逻辑，取而代之的是，编译器会自动为你生成一个私有变量和默认的get/set 操作。</p>
<p>譬如，使用自动属性，我现在可以将上面的代码改写成：</p>
<p>
<div style="border-right: white 2px ridge; padding-right: 10px; border-top: white 2px ridge; padding-left: 10px; font-size: 10pt; padding-bottom: 10px; margin: 10px; border-left: white 2px ridge; padding-top: 10px; border-bottom: white 2px ridge; font-family: courier new; background-color: #eeeeee; word-wrap: break-word">&nbsp;&nbsp;&nbsp;&nbsp;<font color="blue">public&nbsp;class&nbsp;</font><font color="black">Person&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">public&nbsp;string&nbsp;</font><font color="black">FirstName&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">get;&nbsp;set;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="black">}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">public&nbsp;string&nbsp;</font><font color="black">LastName&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">get;&nbsp;set;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="black">}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">public&nbsp;int&nbsp;</font><font color="black">Age&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">get;&nbsp;set;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="black">}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</font> </div>
<p>&nbsp;</p>
<p>或者，我想更简明的话，我可以将空白的地方做进一步压缩，象这样： </p>
<p>
<div style="border-right: white 2px ridge; padding-right: 10px; border-top: white 2px ridge; padding-left: 10px; font-size: 10pt; padding-bottom: 10px; margin: 10px; border-left: white 2px ridge; padding-top: 10px; border-bottom: white 2px ridge; font-family: courier new; background-color: #eeeeee; word-wrap: break-word">&nbsp;&nbsp;&nbsp;&nbsp;<font color="blue">public&nbsp;class&nbsp;</font><font color="black">Person&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">public&nbsp;string&nbsp;</font><font color="black">FirstName&nbsp;{&nbsp;</font><font color="blue">get;&nbsp;set;&nbsp;</font><font color="black">}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">public&nbsp;string&nbsp;</font><font color="black">LastName&nbsp; {&nbsp;</font><font color="blue">get;&nbsp;set;&nbsp;</font><font color="black">}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">public&nbsp;int&nbsp;&nbsp;&nbsp; </font><font color="black">Age&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;</font><font color="blue">get;&nbsp;set;&nbsp;</font><font color="black">}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</font> </div>
<p>&nbsp;</p>
<p>当Orcas版中的C#编译器遇上象上面这样的空的get/set属性的话，它会自动为你在类中生成一个私有成员变量，对这个变量实现一个公开的getter 和setter。这么做的好处是，从类-合同(type-contract)的角度来看，这个类跟我们上面第一个有点冗长的实现看上去完全一样，这意味着，不象公开的成员变量，在将来，我可以在我的属性setter实现中添加验证逻辑，而不用对引用我的类的任何外部组件做改动。</p>
<p><a href="http://community.bartdesmet.net/blogs/" target="_blank">Bart De Smet</a>对使用Orcas三月份CTP版中的自动属性时内部发生的情形作了精彩的描述，你可以<a href="http://community.bartdesmet.net/blogs/bart/archive/2007/03/03/c-3-0-automatic-properties-explained.aspx" target="_blank">在这里阅读他的精彩相关帖子</a>。 </p>
<p><strong>C#和VB语言的新特性：对象初始化器(Object Initializers)</strong></p>
<p>.NET框架中的类型非常依赖于属性的使用。当生成对象实例和使用新的类型时，写出象下面这样的编码是非常常见的情形：</p>
<p>
<div style="border-right: white 2px ridge; padding-right: 10px; border-top: white 2px ridge; padding-left: 10px; font-size: 10pt; padding-bottom: 10px; margin: 10px; border-left: white 2px ridge; padding-top: 10px; border-bottom: white 2px ridge; font-family: courier new; background-color: #eeeeee; word-wrap: break-word">&nbsp;&nbsp;&nbsp;<font color="black">Person&nbsp;person&nbsp;</font><font color="blue">=&nbsp;new&nbsp;</font><font color="black">Person()</font><font color="blue">;<br />
&nbsp;&nbsp;&nbsp;</font><font color="black">person.FirstName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Scott"</font><font color="blue">;<br />
&nbsp;&nbsp;&nbsp;</font><font color="black">person.LastName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Guthrie"</font><font color="blue">;<br />
&nbsp;&nbsp;&nbsp;</font><font color="black">person.Age&nbsp;</font><font color="blue">=&nbsp;</font><font color="maroon">32</font><font color="blue">;</font> </div>
<p>&nbsp;</p>
<p>你有没有想要把这样的编码简化过(也许将其安排在一行上)？使用Orcas中的C#和VB语言编译器的话，你现在可以利用一个称为&#8220;对象初始化器(object Initializers)&#8221;的&#8220;语法甜头(syntactic sugar)&#8221;语言特性来做些简化，将上述代码重写为：</p>
<p>
<div style="border-right: white 2px ridge; padding-right: 10px; border-top: white 2px ridge; padding-left: 10px; font-size: 10pt; padding-bottom: 10px; margin: 10px; border-left: white 2px ridge; padding-top: 10px; border-bottom: white 2px ridge; font-family: courier new; background-color: #eeeeee; word-wrap: break-word">&nbsp;&nbsp;<font color="black">Person&nbsp;person&nbsp;</font><font color="blue">=&nbsp;new&nbsp;</font><font color="black">Person&nbsp;{&nbsp;FirstName</font><font color="blue">=</font><font color="#808080">"Scott"</font><font color="black">,&nbsp;LastName</font><font color="blue">=</font><font color="#808080">"Guthrie"</font><font color="black">,&nbsp;Age</font><font color="blue">=</font><font color="maroon">32&nbsp;</font><font color="black">}</font><font color="blue">;</font> </div>
<p>&nbsp;</p>
<p>然后，编译器就会自动地生成合适的属性setter代码，保持跟前面较冗长的代码例子同样的语意。</p>
<p>除了在初始化类时设置简单的属性值外，对象初始化器特性也允许我们设置更复杂的嵌套(nested)属性类型。譬如，假如我们在上面定义的每个Person类型也拥有一个属于Address类型的叫&#8220;Address&#8221;的属性。我们可以编写下面这样的代码来生成一个新的Person对象，同时设置它的属性，象这样： </p>
<p>
<div style="border-right: white 2px ridge; padding-right: 10px; border-top: white 2px ridge; padding-left: 10px; font-size: 10pt; padding-bottom: 10px; margin: 10px; border-left: white 2px ridge; padding-top: 10px; border-bottom: white 2px ridge; font-family: courier new; background-color: #eeeeee; word-wrap: break-word">&nbsp;&nbsp;&nbsp;<font color="black">Person&nbsp;person&nbsp;</font><font color="blue">=&nbsp;new&nbsp;</font><font color="black">Person&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FirstName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Scott"</font><font color="black">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LastName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Guthrie"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="black">Age&nbsp;</font><font color="blue">=&nbsp;</font><font color="maroon">32</font><font color="black">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Address&nbsp;</font><font color="blue">=&nbsp;new&nbsp;</font><font color="black">Address&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Street&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"One&nbsp;Microsoft&nbsp;Way"</font><font color="black">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;City&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Redmond"</font><font color="black">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;State&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"WA"</font><font color="black">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Zip&nbsp;</font><font color="blue">=&nbsp;</font><font color="maroon">98052<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="black">}<br />
&nbsp;&nbsp;&nbsp;}</font><font color="blue">;</font> </div>
<p>&nbsp;</p>
<p><a href="http://community.bartdesmet.net/blogs/" target="_blank">Bart De Smet</a>对使用Orcas三月份CTP版中的对象初始化器时内部发生的情形也作了精彩的描述，你可以<a href="http://community.bartdesmet.net/blogs/bart/archive/2006/12/04/C_2300_-3.0-Feature-Focus-_2D00_-Part-2-_2D00_-Object-Initializers.aspx" target="_blank">在这里阅读他的精彩相关帖子</a>。 </p>
<p><strong>C#和VB语言的新特性：集合初始化器(Collection Initializers)</strong></p>
<p>对象初始化器很棒，它极大地简化了把对象添加到集合的做法。譬如，假如我要把三个人加到一个基于泛型的类型为Person的List集合中去的话，我可以写下面这样的编码：</p>
<p>
<div style="border-right: white 2px ridge; padding-right: 10px; border-top: white 2px ridge; padding-left: 10px; font-size: 10pt; padding-bottom: 10px; margin: 10px; border-left: white 2px ridge; padding-top: 10px; border-bottom: white 2px ridge; font-family: courier new; background-color: #eeeeee; word-wrap: break-word">&nbsp;&nbsp;<font color="black">List&lt;Person&gt;&nbsp;people&nbsp;</font><font color="blue">=&nbsp;new&nbsp;</font><font color="black">List&lt;Person&gt;()</font><font color="blue">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;</font><font color="black">people.Add(&nbsp;</font><font color="blue">new&nbsp;</font><font color="black">Person&nbsp;{&nbsp;FirstName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Scott"</font><font color="black">,&nbsp;LastName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Guthrie"</font><font color="black">,&nbsp;Age&nbsp;</font><font color="blue">=&nbsp;</font><font color="maroon">32&nbsp;</font><font color="black">}&nbsp;)</font><font color="blue">;<br />
&nbsp;&nbsp;</font><font color="black">people.Add(&nbsp;</font><font color="blue">new&nbsp;</font><font color="black">Person&nbsp;{&nbsp;FirstName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Bill"</font><font color="black">,&nbsp;LastName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Gates"</font><font color="black">,&nbsp;Age&nbsp;</font><font color="blue">=&nbsp;</font><font color="maroon">50&nbsp;</font><font color="black">}&nbsp;)</font><font color="blue">;<br />
&nbsp;&nbsp;</font><font color="black">people.Add(&nbsp;</font><font color="blue">new&nbsp;</font><font color="black">Person&nbsp;{&nbsp;FirstName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Susanne"</font><font color="black">,&nbsp;LastName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Guthrie"</font><font color="black">,&nbsp;Age&nbsp;</font><font color="blue">=&nbsp;</font><font color="maroon">32&nbsp;</font><font color="black">}&nbsp;)</font><font color="blue">;<br />
&nbsp;</font> </div>
<p>&nbsp;</p>
<p>对这个例子，跟我使用C# 2.0编译器要输入的代码相比，单独使用新的对象初始化器特性就能省去12行额外的代码。</p>
<p>但Orcas版中的C#和VB编译器允许我们更进一步，现在同时支持&#8220;集合初始化器(collection initializers)&#8221;，这允许我们避免要写多个Add语句，省下更多的键盘操作：</p>
<p>
<div style="border-right: white 2px ridge; padding-right: 10px; border-top: white 2px ridge; padding-left: 10px; font-size: 10pt; padding-bottom: 10px; margin: 10px; border-left: white 2px ridge; padding-top: 10px; border-bottom: white 2px ridge; font-family: courier new; background-color: #eeeeee; word-wrap: break-word">&nbsp;&nbsp;&nbsp;<font color="black">List&lt;Person&gt;&nbsp;people&nbsp;</font><font color="blue">=&nbsp;new&nbsp;</font><font color="black">List&lt;Person&gt;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">new&nbsp;</font><font color="black">Person&nbsp;{&nbsp;FirstName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Scott"</font><font color="black">,&nbsp;LastName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Guthrie"</font><font color="black">,&nbsp;Age&nbsp;</font><font color="blue">=&nbsp;</font><font color="maroon">32&nbsp;</font><font color="black">},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">new&nbsp;</font><font color="black">Person&nbsp;{&nbsp;FirstName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Bill"</font><font color="black">,&nbsp;LastName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Gates"</font><font color="black">,&nbsp;Age&nbsp;</font><font color="blue">=&nbsp;</font><font color="maroon">50&nbsp;</font><font color="black">},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">new&nbsp;</font><font color="black">Person&nbsp;{&nbsp;FirstName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Susanne"</font><font color="black">,&nbsp;LastName&nbsp;</font><font color="blue">=&nbsp;</font><font color="#808080">"Guthrie"</font><font color="black">,&nbsp;Age&nbsp;</font><font color="blue">=&nbsp;</font><font color="maroon">32&nbsp;</font><font color="black">}<br />
&nbsp;&nbsp;&nbsp;}</font><font color="blue">;</font> </div>
<p>&nbsp;</p>
<p>当编译器遇上上面这样的句法时，它会自动为我们生成象前面的例子一样的集合插入编码。</p>
<p><strong>结语</strong> </p>
<p>作为开发人员，我们现在拥有了简明得多的方式来定义对象，对它们初始化，将它们加入集合内。在运行时，其语意，跟今天的较长的版本的语意，是完全一样的（所以你不必担心行为会改变）。但现在你不需输入那么多字符了，你的代码将既干净又简明。 </p>
<p>在不远的将来，我将发表更多的博客贴子来讨论Orcas版中更多的语言上的改进，包括扩展方法（Extension Methods），Lambdas和匿名类。然后，我将对LINQ做深入讨论，示范它是如何利用所有这些特性来提供一个非常优雅的方式来查询和与数据交互的。</p>
<p>希望本文对你有所帮助，</p>
<p>Scott</p>
<div class="postfoot">
<div>标签： <a href="http://weblogs.asp.net/scottgu/archive/tags/ASP.NET/default.aspx" rel="tag">ASP.NET</a>, <a href="http://weblogs.asp.net/scottgu/archive/tags/.NET/default.aspx" rel="tag">.NET</a>, <a href="http://weblogs.asp.net/scottgu/archive/tags/LINQ/default.aspx" rel="tag">LINQ</a></div>
</div>
 <img src ="http://www.cnblogs.com/BoardPung/aggbug/864887.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42115/" target="_blank">[新闻]谷歌Chrome浏览器即将更换LOGO颜色？</a>]]></description></item><item><title>关于七夕</title><link>http://www.cnblogs.com/BoardPung/archive/2007/08/20/862237.html</link><dc:creator>BoardPung</dc:creator><author>BoardPung</author><pubDate>Mon, 20 Aug 2007 01:22:00 GMT</pubDate><guid>http://www.cnblogs.com/BoardPung/archive/2007/08/20/862237.html</guid><wfw:comment>http://www.cnblogs.com/BoardPung/comments/862237.html</wfw:comment><comments>http://www.cnblogs.com/BoardPung/archive/2007/08/20/862237.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/BoardPung/comments/commentRss/862237.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/BoardPung/services/trackbacks/862237.html</trackback:ping><description><![CDATA[摘要: 我们正处于结婚时代的初级阶段，经过二十几年的努力，虽然取得了结识众多异性的巨大成就，但是人口众多，人均资源相对短缺，局部个人发展很不平衡。&nbsp;&nbsp;<a href='http://www.cnblogs.com/BoardPung/archive/2007/08/20/862237.html'>阅读全文</a><img src ="http://www.cnblogs.com/BoardPung/aggbug/862237.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42101/" target="_blank">[新闻]淘宝网合并阿里妈妈 专家称阿里巴巴或有新战略</a>]]></description></item></channel></rss>