﻿<?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>博客园-Anytao</title><link>http://www.cnblogs.com/anytao/</link><description> 		Anytao | 		inAspnet | 		CLRTeam | 		Life | 		Reader | 		Doc | 		Contact | 		About | 2009, Legend Creation</description><language>zh-cn</language><lastBuildDate>Mon, 06 Jul 2009 06:59:10 GMT</lastBuildDate><pubDate>Mon, 06 Jul 2009 06:59:10 GMT</pubDate><ttl>60</ttl><item><title>[书评杂谈]一本Silverlight的完美征程</title><link>http://www.cnblogs.com/anytao/archive/2009/06/15/anytao-recommand-02-travellinginsilverlight.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Mon, 15 Jun 2009 03:51:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/06/15/anytao-recommand-02-travellinginsilverlight.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1503518.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/06/15/anytao-recommand-02-travellinginsilverlight.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1503518.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1503518.html</trackback:ping><description><![CDATA[<p><strong><a target="_blank" href="http://anytao.net/">anytao.net</a> | <a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a>&nbsp; </span></strong></p>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.06.15 作者：</span><a href="http://about.anytao.com/"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，Anytao原创作品，转贴请注明作者和出处。</span></p>
<blockquote></blockquote>
<p>很早就有为<a href="http://www.dotneteye.cn/silverlight">《Silverlight 2完美征程》</a>推荐的想法了，这源于我自己亲身经历的一点一滴。话说，关于Silverlight，TerryLee是我的导师和益友。他的系列文章《<a href="/Terrylee/archive/2008/03/09/Silverlight2-step-by-step-Tutorials.html">一步一步学Silverlight 2系列</a>》为无数的Silverlight粉丝带来指导和导航，而我自己的Silverlight之路也是从这一系列文章开始的。现在，我很高兴的看到Terry的新书<a href="http://www.dotneteye.cn/silverlight">《Silverlight 2完美征程》</a>隆重上市。</p>
<p><img src="http://images.cnblogs.com/cnblogs_com/anytao/186609/o_terrylee-Silverlight-2.png" border="0" style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" /> </p>
<p>可以说，这本书继续了对《<a href="/Terrylee/archive/2008/03/09/Silverlight2-step-by-step-Tutorials.html">一步一步学Silverlight 2系列</a>》的延续，全书22章包含了UI、控件、图像处理、动画效果等基本概念，以及数据绑定、网络通信、独立存储和浏览器交互等高级内容，全书的最后一些有意思的主题可以为我们的SIlverlight体验收获更多的美味，例如墨迹标注的使用、开发DeepZoom应用，凡此种种、无所不包。<a href="http://www.dotneteye.cn/silverlight">《Silverlight 2完美征程》</a>就像是Silverlight的百科全书，涵盖了Silverlight主题的方方面面，在所有主题的论述中，我们始终能看到富有特色的Terry体，初学者很容易通过One By One式的引导来了解如何、怎样实现相应的功能；除了大量的实例实践，terry将他对技术的理解融入到实例的引导中，例如在网络通信章节的论述中，通过Silverlight与WCF、WebClient、HttpWebRequest以及最新的ADO .NET Data Service通信方式进行不同的通信体验，同时对跨域策略进行了深入的介绍，让读者能够更好的理解silverlight数据通信的深层原理。所以，毫不夸张的说，这是国内最优秀的Silverlight著作，源于国内最优秀的技术专家。</p>
<p>Terry是个认真博识的人，在我所认识的很多专家中，Terry始终保持着谦逊、认真和进取。每天和他的言谈身教，使我惊讶于他如此渊博的技术功底。我新历了他写作过程的艰辛、也感激他认真负责的写作态度，他的经历与能力让我毫不犹豫对<a href="http://www.dotneteye.cn/silverlight">《Silverlight 2完美征程》</a>进行任何毫不掩饰的&ldquo;吹捧&rdquo;。</p>
<p>作为受益者，我拿起这本书为所有有Silverlight兴趣的朋友推荐，大家可以访问本书的官方网站：<a href="http://www.dotneteye.cn/silverlight">http://www.dotneteye.cn/silverlight</a>，了解更多的信息。</p>
<p>&nbsp; </p>
<div class="wp_codebox">
<pre>更多精彩，尽在<a target="_blank" href="http://anytao.net/blog">anytao.net</a></pre>
</div>
<p>&nbsp;</p>
<div id="MySignature">
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/06/15 | <a href="http://anytao.net">http://anytao.net</a> | <a href="http://anytao.net/blog/post/2009/06/15/anytao-recommand-02-travellinginsilverlight.aspx" title="http://anytao.net/blog/post/2009/06/15/anytao-recommand-02-travellinginsilverlight.aspx">http://anytao.net/blog/post/2009/06/15/anytao-recommand-02-travellinginsilverlight.aspx</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</p>
</div><img src ="http://www.cnblogs.com/anytao/aggbug/1503518.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48002/" target="_blank">竞争日趋激烈 微软欲借 Windows 7 扭转战局</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[你必须知道的.NET]第三十二回，，深入.NET 4.0之，Tuple一二</title><link>http://www.cnblogs.com/anytao/archive/2009/06/01/must_net_32.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Sun, 31 May 2009 16:05:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/06/01/must_net_32.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1493310.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/06/01/must_net_32.html#Feedback</comments><slash:comments>48</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1493310.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1493310.html</trackback:ping><description><![CDATA[摘要: Tuple，是函数式编程的概念之一，早见于Elang、F#等动态语言。不过，我第一次听说Tuple还早在2005年园子的Ninputer大牛提出在.NET 2.0实现Tuple的基本想法。
作为.NET 4.0 BCL的一部分，本文晓以一二要点，对Tuple进行一翻分析，以期对这个新成员表示欢迎。&nbsp;&nbsp;<a href='http://www.cnblogs.com/anytao/archive/2009/06/01/must_net_32.html'>阅读全文</a><img src ="http://www.cnblogs.com/anytao/aggbug/1493310.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48001/" target="_blank">上海电信计划2012年80%用户实现100M带宽</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[你必须知道的.NET]第三十一回，深入.NET 4.0之，从“新”展望</title><link>http://www.cnblogs.com/anytao/archive/2009/05/22/must_net_31.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Thu, 21 May 2009 16:36:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/05/22/must_net_31.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1486718.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/05/22/must_net_31.html#Feedback</comments><slash:comments>79</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1486718.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1486718.html</trackback:ping><description><![CDATA[<p><strong><a target="_blank" href="http://anytao.net/">anytao.net</a> | <a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a>&nbsp; </span></strong></p>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.05.22 作者：</span><a href="http://about.anytao.com/"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，Anytao原创作品，转贴请注明作者和出处。</span></p>
<div class="wp_codebox">
<pre><span style="color: gray">/// &lt;summary&gt;
/// </span><span style="color: green">本文开始，将以《.NET 4.0深入》为主线，开始一段体验.NET 4.0的激动旅程。
</span><span style="color: gray">/// &lt;/summary&gt;</span></pre>
</div>
<p>总体来说，这是一篇介绍性的文章，不会涉及过多技术细节和研究过程。但是，作为拉开序幕的第一页，本文以提纲挈领的方式展开对.NET 4.0的初次体验。从What&rsquo;s new的角度，开始我对.NET 4.0新特性的探索之旅。既然是介绍，那么首先给出导航式的链接是必要而必须的，因为一篇小小的篇幅却是难以交代全面What&rsquo;s new in details，所以看官尽情各取所需吧：</p>
<ul>
<li><a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd410112(VS.100).aspx">Visual Studio 2010 in MSDN</a> </li>
<li><a target="_blank" href="http://msdn.microsoft.com/en-us/library/bb386063(VS.100).aspx">What's New in Visual Studio 2010</a> </li>
<li><a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd409230(VS.100).aspx">What's New in the .NET Framework 4</a> </li>
<li><a href="http://msdn.microsoft.com/en-us/library/w0x726c2(VS.100).aspx">.NET Framework 4 Beta 1</a> </li>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=150928">Visual Studio 2010 Samples</a> </li>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=150454">Visual Studio 2010 and .NET Framework 4 Training Kit</a> </li>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=150466">Visual Studio 2010 Videos</a> </li>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=150467">.NET Framework 4 Videos</a> </li>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=150455">Visual Studio 2010 Beta 1 Walkthroughs</a> </li>
</ul>
<p>因为是[<a target="_blank" href="http://book.anytao.com/">你必须知道的.NET</a>]子系列，所以在此我只关注2010发布之后伴随.NET 4.0的新特性，总结起来主要包括以下几个方面：</p>
<ul>
<li>CLR (Common Language Runtime) </li>
<li>DLR (Dynamic Language Runtime) </li>
<li>C# and VB .NET </li>
<li>Web and Networking </li>
<li>Basic class libraries(BCL) </li>
<li>Data </li>
<li>Client </li>
<li>Web </li>
<li>Communications </li>
</ul>
<p>所以，对what&rsquo;s new的解读，我将分为两个大的部分来诠释：</p>
<ul>
<li><strong>Hot Focus</strong>，热点解读。对新特性中值得期待和关注的技术点进行一点整理，因为太多太多了，所以学会抽丝拨茧才是正确之道，在Hot Focus中我们首先对亮点进行一番认知。同时，Hot Focus内容体系也将是为了《深入.NET 4.0》子系列探索的方向和大纲。 </li>
<li><strong>Full View</strong>，.NET 4.0全景图。把概念涉及到各个新增的方面，由此对.NET4.0有个全面和基本的了解。 </li>
</ul>
<h2><strong>Hot Focus</strong></h2>
<p>在我看来，值得Hot Focus的主要包括以下几个方面：</p>
<ul>
<li>CLR &amp; DLR </li>
<li>C# </li>
<li>Web </li>
<li>Cloud </li>
<li>Data </li>
<li>F# </li>
</ul>
<p>下面进行一一分解。</p>
<h3><strong>CLR 4.0</strong></h3>
<p>是的，不用怀疑，CLR 4.0来了，从CLR 2.0一跃升级到CLR 4.0，我们对新建项目进行反编译，即可从Manifest中获取当前CLR的版本信息，例如：</p>
<p><a href="/anytao/admin/$anytao-insidenet-31-01[3].png"><img height="233" width="504" src="http://images.cnblogs.com/cnblogs_com/anytao/186609/o_anytao-insidenet-31-01.png" alt="anytao-insidenet-31-01" border="0" title="anytao-insidenet-31-01" style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" /></a> </p>
<p>可见没有重量级的新成员，.NET产品组是不敢贸然为新生儿挂上如此响亮的封号。那么这个分量足够的新家伙到底是谁呢？</p>
<p>答案是：</p>
<ul>
<li>DLR（Dynamic Language Runtime），动态语言运行时，提供了对动态语言在CLR级别的支持。 </li>
<li>Parallel Computing，并行计算，在多核时代，并行计算已经不可避免。新的平台下，对于并行的支持也随之而来，我们不需要在直接对线程进行管理，Parallel和Task类，当然还有PLINQ（Parallel LINQ）都将闪亮登场。 </li>
<li>GC，GC也有新变化，我们拭目以待。 </li>
<li>Convariance and Contravariance，逆变与协变，解决了泛型继承的某些问题，算是一场迟来的完善。 </li>
<li>Interoperability，互操作将不依赖于原有的RIAs，新的CLR确保了类型安全操作。 </li>
<li>Lazy Initialization，在未来的日子，通过System.Lazy&lt;T&gt;来为你的实例提供延迟初始化成为可能，这将意味着你的类型可以在实际需要的时候才进行实例化操作、分配内存空间，对性能的控制达到了新的高度。 </li>
<li>In-Process Side-by-Side Execution，In-Process Side-by-Side hosting解决了不同版本应用在CLR 4.0平台下运行的问题，我们以后详细讨论。 </li>
</ul>
<p>除此之外，还包括：</p>
<ul>
<li>Security </li>
<li>ETW Events </li>
<li>Code Contracts </li>
<li>Profiling </li>
</ul>
<p>所有的概念，我们都将随后品味。那是因为，所有的概念都是重量级的。</p>
<h3><strong>C# 4.0</strong></h3>
<p>C# 4.0主要引入了以下程序元素：</p>
<ul>
<li>Office Programmability </li>
<li>Dynamic </li>
<li>Covariance and Contravariance </li>
<li>Type Equivalence </li>
</ul>
<p>&nbsp;</p>
<p>关于.NET 4.0和C# 4.0的若干概念，我在[<a href="/anytao/archive/2009/05/11/must_net_30.html">[你必须知道的.NET]第三十回：.NET十年（下）</a>]已经进行过介绍性的演示与探讨，大家不妨一睹为快。</p>
<h3><strong>ASP .NET 4.0</strong></h3>
<p><a target="_blank" href="http://msdn.microsoft.com/en-us/library/s57a598e.aspx">What's New in ASP.NET and Web Development</a></p>
<p>对于Web开发而言, ASP .NET 4.0从3.5开始就已经提供了很多未集成的新东西，其中包括了类似于MVC在内的很多了不起的改变。所以，对于.NET 4.0而言，我们对于Web开发的贡献，在于对过去的整理和再生，值得关注的内容主要包括：</p>
<ul>
<li>MVC，虽然VS2010 Beta1还没有将MVC Framework整合在内，但是微软承诺在Beta2中我们就可以看到新的MVC身影。 </li>
<li>Dynamic Data，对，早已领略了如何一分钟之内开发一个增删改查式的动态站点，在ASP .NET 4.0中实现数据驱动的Web开发更加Powerful了。 </li>
<li>Web Form，在ASP .NET 4.0传统的Web Form开发被注入了更多的新特性，我们可以像MVC Application那样无缝的使用ASP .NET Routing，对于数据源提供了Filtering支持，更多的View state控制，还有好多好多。。。 </li>
<li>EntityDataSource Control，支持基于Entity Framework的数据绑定控制。 </li>
</ul>
<p>还有很多，详见<a target="_blank" href="http://msdn.microsoft.com/en-us/library/s57a598e.aspx">What's New in ASP.NET and Web Development</a></p>
<h3><strong>Data</strong></h3>
<p><a target="_blank" href="http://msdn.microsoft.com/en-us/library/ex6y04yf(VS.100).aspx">What's New in ADO.NET</a></p>
<p>在数据方面主要还是ADO .NET Entity Framework的增强和Expression Tree的更多支持。EF主要体现在以下方面：</p>
<ul>
<li>Persistence-Ignorant Objects，这个特性是令人欢欣鼓舞的，在新的EF框架下，EF实体类和非EF实体类都应用EF提供的数据支持，这将意味着原有的数据模型也可以畅享EF了。 </li>
<li>Deferred Loading of Related Objects，如果你没有体会过原来EF处理延迟加载使用的方式时： </li>
</ul>
<div class="wp_codebox">
<pre><span style="color: blue">if </span><span>(!user.RoleReference.IsLoaded)
{
    user.RoleReference.Load();
}</span></pre>
</div>
<p>是很难理解，这一新特性为代码优化给出了机会。</p>
<ul>
<li>Functions in LINQ to Entities Queries，一切皆LINQ的时代，这点也不奇怪。 </li>
<li>Customized Object Layer Code Generation，为EF数据设计器提供了自动生成代码的可配置向导，更加人性化的选择。 </li>
<li>还包括：Complex Type Support、Naming Service、Improved Model Brower Funcationality。 </li>
</ul>
<p>另外，对于Expression Tree，控制了几个新的类型支持，例如 <a href="http://msdn.microsoft.com/en-us/library/system.linq.expressions.loopexpression(VS.100).aspx">LoopExpression</a> 和<a href="http://msdn.microsoft.com/en-us/library/system.linq.expressions.tryexpression(VS.100).aspx">TryExpression</a>。</p>
<h3><strong>BCL</strong></h3>
<p>基础类库的更新，是每次.NET版本更新的重要内容，.NET 4.0中基础类库的新增内容，同样惊为天人。在此我仅列举几个重要的更新，更多的内容参考MSDN。</p>
<ul>
<li>Collections 
<ul>
<li>BigInterger </li>
<li>SortedSet&lt;T&gt; </li>
<li>Tuples </li>
</ul>
</li>
<li>I/O 
<ul>
<li>File System Enumeration </li>
<li>Memory-Mapped Files </li>
<li>Isolated Storage </li>
<li>Compression </li>
</ul>
</li>
<li>Exception </li>
<li>Reflection </li>
<li>64-bit </li>
<li>Application Domain Resource Monitoring </li>
<li>Threading </li>
<li>Unified Model for Cancellation </li>
<li>Thread-Safe Collection </li>
<li>Synchronization Primitives </li>
<li>。。。 </li>
<li>。。。 </li>
<li>很多很多，我们的策略显然是随用随取。 </li>
</ul>
<h3><strong>Cloud</strong></h3>
<p>云计算将不可避免的到来，在.NET 4.0平台下，Azure Service应用将眼花缭乱，但是可以肯定的是开发模式更加简化，大量的问题需要时间在以后，我们到时再来掂量一二。</p>
<h3><strong>F#</strong></h3>
<p>一个对我全新而又有足够吸引力的新语言，以后再说吧:-) </p>
<h2><strong>Full View</strong></h2>
<p>&nbsp;</p>
<p>除了以上的重点内容，作为.NET 4.0大家族的一部分，还有很多很多令人兴奋的新东西加入进来，令我们叹息一切太多太快的同时，又带来一丝丝惊喜和心动。废话少说，对其进行一番简单的整理：</p>
<ul>
<li>MEF </li>
<li>WPF </li>
<li>WCF 4.0 </li>
<li>WF 4.0 </li>
<li>Appliction Server（代号Dublin） </li>
</ul>
<h2><strong>结论</strong></h2>
<p>.NET 4.0来了，在这个夏天。在蚊子和啤酒相伴的深夜，我将继续[<a target="_blank" href="http://book.anytao.com/">你必须知道的.NET</a>] 系列的完善，将自己对于.NET 4.0新特性的探索形成[深入.NET 4.0]这样一个子系列。同样是一如既往的将角度把握在语言和平台本质的探索，可能的角度上，最佳实践式的应用和国外最新论调的共享同样是这一新生力量关注的话题。好戏才刚开始，我们继续在路上。</p>
<p>&nbsp;</p>
<p><span style="color: #ff0000;">注：<a href="http://book.anytao.com/">你必须知道的.NET</a>, .NET 4.0子系列以VS2010 Beta1和.NET 4.0 Beta1为基础，任何后续更新造成的可能不同，我将尽力完善。</span>&nbsp;</p>
<p>&nbsp;</p>
<h3>参考文献</h3>
<ul>
<li><a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd410112(VS.100).aspx">Visual Studio 2010 in MSDN</a> </li>
<li><a target="_blank" href="http://msdn.microsoft.com/en-us/library/bb386063(VS.100).aspx">What's New in Visual Studio 2010</a> </li>
<li><a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd409230(VS.100).aspx">What's New in the .NET Framework 4</a> </li>
<li><a href="http://msdn.microsoft.com/en-us/library/w0x726c2(VS.100).aspx">.NET Framework 4 Beta 1</a> </li>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=150928">Visual Studio 2010 Samples</a> </li>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=150454">Visual Studio 2010 and .NET Framework 4 Training Kit</a> </li>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=150466">Visual Studio 2010 Videos</a> </li>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=150467">.NET Framework 4 Videos</a> </li>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=150455">Visual Studio 2010 Beta 1 Walkthroughs</a> </li>
</ul>
<p>&nbsp;</p>
<div class="wp_codebox">
<pre>更多精彩，尽在<a target="_blank" href="http://anytao.net/blog">anytao.net</a></pre>
</div>
<p>&nbsp;</p>
<div id="MySignature">
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/05/22 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a> | <a href="http://anytao.net/blog/post/2009/05/22/anytao-insidenet-31-net4newfullview.aspx" title="http://anytao.net/blog/post/2009/05/22/anytao-insidenet-31-net4newfullview.aspx">http://anytao.net/blog/post/2009/05/22/anytao-insidenet-31-net4newfullview.aspx</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</p>
</div><img src ="http://www.cnblogs.com/anytao/aggbug/1486718.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48000/" target="_blank">数万名网友签名抗议星际争霸2取消局域网功能</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[TechShare]#2, MVC Walkthrough</title><link>http://www.cnblogs.com/anytao/archive/2009/05/12/anytao-techshare-02-mvcwalkthrough.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Tue, 12 May 2009 11:18:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/05/12/anytao-techshare-02-mvcwalkthrough.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1455173.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/05/12/anytao-techshare-02-mvcwalkthrough.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1455173.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1455173.html</trackback:ping><description><![CDATA[摘要: MVC Walkthrough是公司关于MVC技术培训系列的第一部分，在第一部分中我对ASP .NET MVC进行了一次流水线似的访问，从MVC的基本要素开始，探讨MVC、MVP和WebForm的区别与种种，然后深入讨论什么是MVC，什么是M、什么是V、什么是C，最后自然少不了Routing和Execution Process，近两个小时的时间虽然太短，但是该有的引导性基础都包括在内了。&nbsp;&nbsp;<a href='http://www.cnblogs.com/anytao/archive/2009/05/12/anytao-techshare-02-mvcwalkthrough.html'>阅读全文</a><img src ="http://www.cnblogs.com/anytao/aggbug/1455173.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47999/" target="_blank">Silverlight打造杰克逊纪念专题</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[TechShare]#1, Travelling in Silverlight</title><link>http://www.cnblogs.com/anytao/archive/2009/05/12/anytao-techshare-01-travellinginsilverlight.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Tue, 12 May 2009 11:15:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/05/12/anytao-techshare-01-travellinginsilverlight.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1455171.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/05/12/anytao-techshare-01-travellinginsilverlight.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1455171.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1455171.html</trackback:ping><description><![CDATA[摘要: 博客园北京.NET俱乐部第一次技术活动，我的技术演讲。&nbsp;&nbsp;<a href='http://www.cnblogs.com/anytao/archive/2009/05/12/anytao-techshare-01-travellinginsilverlight.html'>阅读全文</a><img src ="http://www.cnblogs.com/anytao/aggbug/1455171.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47999/" target="_blank">Silverlight打造杰克逊纪念专题</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[开发故事]第四回：应用反射在运行时动态获取类型信息</title><link>http://www.cnblogs.com/anytao/archive/2009/05/12/anytao-devstory-04-dynamictypeinfo.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Tue, 12 May 2009 03:21:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/05/12/anytao-devstory-04-dynamictypeinfo.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1454718.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/05/12/anytao-devstory-04-dynamictypeinfo.html#Feedback</comments><slash:comments>30</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1454718.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1454718.html</trackback:ping><description><![CDATA[摘要: 一个简单的技巧，一个补充的说明（对hbfly老兄的）。反射的能量是强大的，强大到我们可以轻而易举的对元数据信息进行读取和操作，正是如此很多基于Attribute和Reflection的巧妙设计就油然而生了。例如，在我的项目中就通过定义Attribute来实现实体类的string属性在get/set时统一进行Trim操作，保证了提交数据没有冗余，同时不必在其他地方来特别关注实现对于string.Trim()的调用。&nbsp;&nbsp;<a href='http://www.cnblogs.com/anytao/archive/2009/05/12/anytao-devstory-04-dynamictypeinfo.html'>阅读全文</a><img src ="http://www.cnblogs.com/anytao/aggbug/1454718.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47999/" target="_blank">Silverlight打造杰克逊纪念专题</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[你必须知道的.NET]第三十回：.NET十年（下）</title><link>http://www.cnblogs.com/anytao/archive/2009/05/11/must_net_30.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Sun, 10 May 2009 17:51:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/05/11/must_net_30.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1453864.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/05/11/must_net_30.html#Feedback</comments><slash:comments>50</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1453864.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1453864.html</trackback:ping><description><![CDATA[<p><strong><a target="_blank" href="http://anytao.net/">anytao.net</a> | <a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a>&nbsp; </span></strong></p>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.05.11 作者：</span><a href="http://about.anytao.com/"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，Anytao原创作品，转贴请注明作者和出处。</span></p>
<div class="wp_codebox">
<pre><span style="color: gray">/// &lt;summary&gt;
/// </span><span style="color: green">本文部分内容，已发表于《程序员》杂志第二期《C#，语言的变迁》
</span><span style="color: gray">/// &lt;/summary&gt;</span></pre>
</div>
<h2><strong>引言</strong></h2>
<p>语言是程序开发者行走江湖的手上利器，各大门派的高手在论坛、博客为了自家门派争吵不已早是技术世界中的亮丽风景，虽多少为刚刚踏入江湖的新手提供了思考的素材，但也同时迷惑了初出茅庐的前行方向。 </p>
<p>本文不欲计较门派的高下，旨在明辨技术的真谛，这就是.NET平台下的开发利器：C#语言，并从其变迁的进程中对于.NET技术发展把玩一番。 </p>
<p>在下篇，我们将从历史走来，对.NET的未来做个展望性的了解，具体而言就是.NET 4.0的新东西。</p>
<h2><b>.NET之，未来武器</b><b></b></h2>
<p>无论如何，.NET 4.0已经在叩开新年的大门之时，以高调的姿态迎来一片掌声。广大的技术爱好者不会等待太长的时间，就能感受C#发展中的又一次变革。随着.NET 4.0在2009年的发布，我们对于C# 4.0的关注也将与日俱增。总体而言，C# 4.0的重头戏主要着眼在以下几个方面： </p>
<ul>
<li>动态编程 </li>
<li>并行计算 </li>
<li>后期绑定 </li>
<li>协变与逆变 </li>
</ul>
<p>废话少说，接下来我们一一领略C# 4.0中的语言特性。 </p>
<h3><b>动态编程</b></h3>
<p>众所周知，C#是静态强类型语言。而在很多情况下，提供&ldquo;动态&rdquo;行为，是常常发生的事情，例如通过反射在运行时访问.NET类型、调用动态语言对象、访问COM对象等，都无法以静态类型来获取。因此， C# 4.0引入的又一个全新的关键字dynamic，也同时引入了改善静态类型与动态对象的交互能力，这就是动态查找（Dynamic Lookup）例如： </p>
<div class="wp_codebox">
<div class="wp_codebox">
<pre><span style="color: green">// Release : code06, 2009/05/07
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">public static void </span>Main()
{
     dynamic d = GetDynamicObject();               
     d.MyMethod(22);                  <span style="color: green">// 方法调用   
    </span>d.A = d.B;                       <span style="color: green">// 属性赋值
    </span>d[&ldquo;one&rdquo;] = d[&ldquo;two&rdquo;];             <span style="color: green">// 索引器赋值
    </span><span style="color: blue">int </span>i = d + 100;                 <span style="color: green">// 运算符调用
    </span><span style="color: blue">string </span>s = d(1,2);               <span style="color: green">// 委托调用
</span>}</pre>
</div>
</div>
<p>就像一个object可以代表任何类型，dynamic使得类型决断在运行时进行，方法调用、属性访问、委托调用都可动态分派。同时，动态特性还体现在构建一个动态对象，在C# 4.0实现IDynamicObject接口的类型，可以完全定义动态操作的意义，通过将C#编译器作为运行时组件来完成由静态编译器延迟的操作，例如： </p>
<div class="wp_codebox">
<pre><span style="color: blue">dynamic </span>d = <span style="color: blue">new </span>Foo();  
<span style="color: blue">string </span>s;   
  
d.MyMethod(s, 3, <span style="color: blue">null</span>);</pre>
</div>
<p>在具体执行过程中，C#的运行时绑定器基于运行时信息，通过反射获取d的实际类型Foo，然后在Foo类型上就MyMethod方法进行方法查找和重载解析，并执行调用，这正是动态调用的背后秘密：DLR。在.NET 4.0中将引入重要的底层组件DLR（Dynamic Language Runtime，动态语言运行时），除了实现动态查找的基础支持，DLR也同时作为基础设施为类似于IronRuby、IronPython这样的动态语言提供统一的互操作机制。总而言之，动态编程将为C#在以下领域产生巨大的变革： </p>
<ul>
<li>Office编程与其他COM交互。 </li>
<li>动态语言支持，在C#中消费IronRuby动态语言类型将并非难事，体验动态语言特性指日可待。 </li>
<li>增强反射支持。 </li>
</ul>
<p>以调用IronRython为例，我们只需引入IronPython.dll, IronPython.Modules.dll, and Microsoft.Scripting.dll，即可通过创建ScriptRuntime在C#中HostingIronPython环境，进而来操作动态语言的类型信息。 </p>
<div class="wp_codebox">
<pre>ScriptRuntime py = Python.CreateRuntime();
<span style="color: blue">dynamic </span>mypy = py.UseFile(<span style="color: #a31515">"myfile.py"</span>);

<span style="color: #2b91af">Console</span>.WriteLine(mypy.MyMethod(<span style="color: #a31515">"Hello"</span>));</pre>
</div>
<p>虽然从微软当前提供的技术资料和CTP演示中，动态查找还存在或多或少的问题，但是在&ldquo;动态&rdquo;大行其道的今天，我们无法回避也必须拥抱这个未来的主角，因为我坚信明天会更好。 </p>
<h3><strong>并行计算</strong></h3>
<p>并行计算的出现，是计算机科学发展的必然结果，随着计算机硬件的迅猛发展，在多核处理器上工作已经是既存事实，而传统的编程模式必须兼容新的硬件环境才能使计算机性能达到合理的应用效果。用Anders大师的话说：未来5到10年，并行计算将成为主流编程语言不可忽视的方向，而4.0为C#打响了实现并发的第一枪。 </p>
<p>未来的.NET Framework 4.0中将集成TPL（Task Parallel Library）和PLINQ（Parallel LINQ），这也意味着未来我们可以应用C# 4.0实现并行化应用，在统一的工作调度程序下进行硬件的并行协调，这将大大提高应用程序的性能同时降低现存并发模型的复杂性。 </p>
<p>那么，我们应该一睹为快应用C#武器来开发并发环境下的超酷感受，在System.Threading.Parallel 静态类提供了三个重要的方法For、Foreach、Invoke可以为我们小试牛刀： </p>
<div class="wp_codebox">
<pre><span style="color: green">//应用TPL，执行并行循环任务
</span><span style="color: #2b91af">Parallel</span>.For(0, 10, i =&gt;
{
    DoSomething(i);
});</pre>
</div>
<p>在线程争用执行情况下，相同的操作在双核平台下运行，以StopWatch进行精确时间测试，并行环境下的执行时间为 2001ms，而非并行环境下的执行时间为4500ms，并行运算的魅力果然名不虚传。我们再接再厉应用PLINQ执行对于并行运算的查询、排序等，当前PLINQ支持两种方式ParallelEnumerable类和ParallelQuery类，例如： </p>
<div class="wp_codebox">
<pre><span style="color: blue">int</span>[] data = <span style="color: blue">new int</span>[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
<span style="color: blue">int</span>[] selected = (<span style="color: blue">from </span>x <span style="color: blue">in </span>data.AsParallel()
                  <span style="color: blue">select </span>x + 1).ToArray();</pre>
</div>
<p>更详细的对比示例留待读者在实践中对此进行讨论，并行计算为托管代码在多核环境下的性能优化提供了统一的解决方案，而未来我们会做的更好。 </p>
<p>备注：实际上，我们可以选择下载安装Microsoft Parallel Extensions to the .NET Framework 3.5June 2008 CTP包，就可以在.NET 3.5环境下体验并行计算的无穷魅力。 </p>
<h3><strong>协变和逆变</strong></h3>
<p>协变和逆变，是为解决问题而生的。而要理清解决什么样的问题，需要首先从理清几个简单的概念开始。首先我们进行一点操作： </p>
<div class="wp_codebox">
<pre><span style="color: #2b91af">Derived </span>d = <span style="color: blue">new </span><span style="color: #2b91af">Derived</span>();
<span style="color: #2b91af">Base </span>b = d;</pre>
</div>
<p>Derived类型继承自Based类型，由Derived引用可以安全的转换为Based引用，而这种转换能力可以无缝的实现在Derived数组和Base数组，例如： </p>
<div class="wp_codebox">
<pre><span style="color: #2b91af">Derived</span>[] ds = <span style="color: blue">new </span><span style="color: #2b91af">Derived</span>[5];
<span style="color: #2b91af">Base</span>[] bs = ds;</pre>
</div>
<p>而这种原始转换（由子类转换为父类）方向相同的可变性，被称为协变（covariant）；其反向操作则被称为逆变（contravariant）。当同样的情形应用于泛型时，例如： </p>
<div class="wp_codebox">
<pre><span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">Derived</span>&gt; ds = <span style="color: blue">new </span><span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">Derived</span>&gt;();
<span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">Base</span>&gt; bs = ds;</pre>
</div>
<p>类似的操作却是行不通的。所以，这就成为C# 4.0中完善的问题&mdash;&mdash;泛型的协变与逆变： </p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code07, 2009/05/07
// Author  : Anytao, http://www.anytao.com
</span><span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">Base</span>&gt; bs = <span style="color: blue">new </span><span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">Base</span>&gt;();
<span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">Derived</span>&gt; ds = <span style="color: blue">new </span><span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">Derived</span>&gt;();

bs = ds;    <span style="color: green">//List&lt;T&gt;支持对T协变
</span>ds = bs;    <span style="color: green">//List&lt;T&gt;支持对T逆变</span></pre>
</div>
<p>而在C# 4.0中，伴随着协变与逆变特性的加入，C#引入两个in和out关键字来解决问题。 </p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code08, 2009/05/07
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">public interface </span><span style="color: #2b91af">ICovariant</span>&lt;<span style="color: blue">out </span>T&gt;
{
    T MyAction();
}

<span style="color: blue">public interface </span><span style="color: #2b91af">IContravariant</span>&lt;<span style="color: blue">in </span>T&gt;
{
    <span style="color: blue">void </span>MyAction(T arg);
}</pre>
</div>
<p>其中，out表示仅能作为返回值的类型参数，而in表示仅能作为参数的类型参数，不过一个接口可以既有out又有in，因此既可以支持协变、支持逆变，也可以同时支持，例如： </p>
<div class="wp_codebox">
<pre><span style="color: blue">public interface </span><span style="color: #2b91af">IBoth</span>&lt;<span style="color: blue">out </span>U, <span style="color: blue">in </span>V&gt;
{
}</pre>
</div>
<h3><strong>命名参数和可选参数</strong></h3>
<p>命名参数和可选参数是两个比较简单的特性，对于熟悉其他编程语言的开发者来说可选参数并不陌生，为参数提供默认值时就是可选参数： </p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code09, 2009/05/07
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">public void </span>MyMethod(<span style="color: blue">int </span>x, <span style="color: blue">int </span>y = 10, <span style="color: blue">int </span>z = 100)
{
}</pre>
</div>
<p>因此，我们可以通过调用MyMethod(1)、MyMethod(1, 2)方式来调用MyMethod方法。而命名参数解决的是传递实参时，避免因为省去默认参数造成的重载问题，例如省去第二个参数y调用时，即可通过声明参数名称的方式来传递： </p>
<div class="wp_codebox">
<pre>MyMethod(20, z: 200);</pre>
</div>
<p>相当于调用MyMethod(20, 10, 200)，非常类似于Attribute的调用方式。虽然只是小技巧，但也同时改善了方法重载的灵活性和适配性，体现了C#语言日趋完美的发展轨迹。 </p>
<p>当然，除此之外.NET 4.0还增加了很多值得期待的平台特性，也将为C#编码带来前所未有的新体验。 </p>
<h2><b>.NET之，趋势不可逆转</b></h2>
<p>预测未来，在技术世界是常有的事儿。从高级语言的发展历史来看，编程世界从来就没有停止过脚步，变革时时发生、创新处处存在。以技术人员的角度来观摩未来，带着C# 4.0的脚步来看展望， 除了在函数式编程、并行计算和动态特性上大展拳脚，Meta Programming的概念已然浮出水面，将编译器变成一个Service，你可以自由控制在编译器和运行期的逻辑，那是多么美好而向往的未来呀，所以，我们坚信 4.0之后还有广阔的天地随着语言的变迁变得更加开阔。 </p>
<p>概括Anders大师在C#设计过程中的思想，C#是语言美学的集大成者。例如，当使用foreach进行循环遍历之后，当应用using语句代替try/finally实现强制资源管理，当应该attribute进行运行时反射，当以LINQ进行语言级别的信息查询，这些语言级别的支持为C#实现面向对象编程带来强大的功能动力和美学感受。</p>
<p>&nbsp;</p>
<p><span style="color: #ff0000;">注：本文代码在VS2010 CTP基础上开发，未检测任何版本更新所带来的不同，望明察。</span></p>
<h3>参考文献</h3>
<p>（Web）<a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html">http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html</a> </p>
<p>（Web）<a href="http://weblogs.asp.net/podwysocki/archive/2008/05/24/what-is-the-future-of-c-anyways.aspx">http://weblogs.asp.net/podwysocki/archive/2008/05/24/what-is-the-future-of-c-anyways.aspx</a> </p>
<p>（Web）New features in C# 4.0 </p>
<p>（Web）<a href="http://msdn.microsoft.com/en-us/magazine/cc163340.aspx">http://msdn.microsoft.com/en-us/magazine/cc163340.aspx</a> </p>
<p><b>作者简介：</b> </p>
<p>王涛，网名Anytao，微软C# MVP，高级软件工程师，机械工程硕士，《你必须知道的.NET》一书作者，主要研究方向为.NET底层架构和企业级系统应用。现就职于某软件公司负责架构设计、软件开发和项目管理方面的工作。作者对.NET基础架构和CLR底层运行机制有浓厚的研究兴趣和造诣，熟悉ASP.NET、XML、WCF、SQL Server相关技术，对面向对象、设计模式和软件架构有一定的研究与实践经验。他的联系方式如下：<a href="/Anytao">http://www.cnblogs.com/Anytao</a> </p>
<p>&nbsp;</p>
<div class="wp_codebox">
<pre>更多精彩，尽在<a target="_blank" href="http://anytao.net/blog">anytao.net</a></pre>
</div>
<p>&nbsp;</p>
<div id="MySignature">
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/05/11 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a> | <a href="http://anytao.net/blog/post/2009/05/08/anytao-insidenet-30-tenyear-part02.aspx" title="http://anytao.net/blog/post/2009/05/07/anytao-insidenet-30-tenyear-part02.aspx">http://anytao.net/blog/post/2009/05/08/anytao-insidenet-30-tenyear-part02.aspx</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</p>
</div><img src ="http://www.cnblogs.com/anytao/aggbug/1453864.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47998/" target="_blank">传诺基亚正在开发Android手机</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[一步一步MVC]第六回：什么是MVC（上）？</title><link>http://www.cnblogs.com/anytao/archive/2009/05/10/anytao-mvc-06-introductionmvc-part1.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Sun, 10 May 2009 09:20:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/05/10/anytao-mvc-06-introductionmvc-part1.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1453703.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/05/10/anytao-mvc-06-introductionmvc-part1.html#Feedback</comments><slash:comments>19</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1453703.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1453703.html</trackback:ping><description><![CDATA[摘要: 所谓MVC，其实就是M、V、C而已。归根揭底，MVC是一种表现模式，是一种软件架构模式。其中有几个重要的概念：

M，Model， 引用系统数据，管理系统功能并通知View更改用户操作。 
V，View，就是用户接口，用于显示数据。 
C，Controller ，将用户操作映射到Model，并操作视图。 
R，Routing ，MVC的奥秘在于通过Routing实现了对URL的路由选择，完成了上述3个基本概念的基础逻辑。&nbsp;&nbsp;<a href='http://www.cnblogs.com/anytao/archive/2009/05/10/anytao-mvc-06-introductionmvc-part1.html'>阅读全文</a><img src ="http://www.cnblogs.com/anytao/aggbug/1453703.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47996/" target="_blank">7月编程语言排行榜</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[你必须知道的.NET]第二十九回：.NET十年（上）</title><link>http://www.cnblogs.com/anytao/archive/2009/05/08/must_net_29.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Thu, 07 May 2009 16:15:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/05/08/must_net_29.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1452310.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/05/08/must_net_29.html#Feedback</comments><slash:comments>79</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1452310.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1452310.html</trackback:ping><description><![CDATA[<p><strong><a target="_blank" href="http://anytao.net/">anytao.net</a> | <a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a>&nbsp; </span></strong></p>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.05.08 作者：</span><a href="http://about.anytao.com/"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，Anytao原创作品，转贴请注明作者和出处。</span></p>
<div class="wp_codebox">
<pre><span style="color: gray">/// &lt;summary&gt;
/// </span><span style="color: green">本文部分内容，已发表于《程序员》杂志第二期《C#，语言的变迁》
</span><span style="color: gray">/// &lt;/summary&gt;</span></pre>
</div>
<h2><strong>引言</strong></h2>
<p>语言是程序开发者行走江湖的手上利器，各大门派的高手在论坛、博客为了自家门派争吵不已早是技术世界中的亮丽风景，虽多少为刚刚踏入江湖的新手提供了思考的素材，但也同时迷惑了初出茅庐的前行方向。</p>
<p>本文不欲计较门派的高下，旨在明辨技术的真谛，这就是.NET平台下的开发利器：C#语言，并从其变迁的进程中对于.NET技术发展把玩一番。</p>
<p>在上篇，我们走在历史，对.NET的过去尤其是c#语言做以回顾，具体而言就是.NET 1.0、2.0、3.0的一路走来。</p>
<h2><b>.NET之，历史脚步</b></h2>
<p>C#十年了。这个日期是从Anders Hejlsberg在1998年组建C#团队开始算起的，掐指算来已是十年有余了。作为.NET平台下的静态强类型语言，在过去10年的发展历程中披荆斩棘，已经逐渐成为应用开发语言中的佼佼者。从TIOBE开发语言排行榜的最新统计来看，C#位居第六成为开发语言市场的顶级产品：</p>
<p>表 1 TIOBE开发语言排行榜</p>
<p><a href="/anytao/admin/$o_anytao-insidenet-29-01[1][2].png"><img height="244" width="236" src="http://images.cnblogs.com/cnblogs_com/anytao/186609/o_anytao-insidenet-29-01.png" alt="o_anytao-insidenet-29-01[1]" border="0" title="o_anytao-insidenet-29-01[1]" style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" /></a> </p>
<p>（注：此为2008年12月的TIOBE开发语言排行榜，参考<a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html">http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html</a>）</p>
<p>因此，在我们讲解历史的开始，将C#发展历史中的里程碑作以标记，来感受一下C# 10年的发展历程，为每开发者在心底搭起一座通往未来的桥梁。</p>
<p><a href="/anytao/admin/$o_anytao-insidenet-29-02[1][2].png"><img height="194" width="244" src="http://images.cnblogs.com/cnblogs_com/anytao/186609/o_anytao-insidenet-29-02.png" alt="o_anytao-insidenet-29-02[1]" border="0" title="o_anytao-insidenet-29-02[1]" style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" /></a>&nbsp;</p>
<p>下面我们分别从不同的历史阶段来了解C#语言的变迁，并讨论在每个变迁的里程碑上值得品味的闪光点，并由此为未来的发展打一个基础。</p>
<h3><b>1.0</b><b>，从诞生到立足</b></h3>
<p>2000年之夏，微软大当家&shy;&shy;&mdash;&mdash;盖茨先生着手战略调整，微软大刀阔斧的进行了技术改革与创新，并由此为世界带来一个新的名词，这就是.NET。那么什么是.NET呢？在.NET这一概念诞生之初，这一概念连微软本身都充满了定位的错乱和迷茫，以至于一时之间处处皆为.NET，大有一统江湖之势。随着.NET平台的逐渐完善，概念和定位上的混乱已经日渐清晰，作为这场变革中的一项重要内容，一种全新的、能够适应.NET平台特性的高级语言C#也随之诞生。这一任务理所当然的落在了Anders Hejlsberg的身上，作为Delphi之父，大师级的Anders从1998年11月开始领导了他的小组为这个世界带来全新的语言宠儿，这就是：C#。</p>
<p>初出茅庐的C#，就像羞羞答答的小姑娘，步步留心、时时在意，学着他人的模样，生怕在前辈面前丢脸。当她以全新的姿态出现在万千程序开发者眼前时，其兼取百家之长、优雅简洁之态、摒弃复杂之弊的特性，立时令所有的观望折服。在迎来所有目光的关注的同时，迅速成为高级语言战场的骄子。</p>
<p>那么，C#诞生之初兼取百家之长，具体都有哪些优秀品质呢，总结起来主要体现在两个方面包括：</p>
<ul>
<li>面向对象编程。C#实现对属性、事件、委托、方法、索引器、构造器的全面支持，为面向对象的封装、继承、多态和接口提供了语言级别的支持。以继承为例，c#支持单实现继承和多接口继承，摒弃了C++中多继承带来的复杂性。 </li>
<li>跨平台运行时支持。CLR是.NET平台下应用程序的通用语言运行时，是C#程序赖以生存的跨平台环境，因此C#具有了.NET平台语言的所有优势，通用类型系统、自动内存管理、统一异常处理、完全的FCL访问权，都成为C#无与伦比的优势所在。 </li>
</ul>
<h3><b>2.0</b><b>，变革之作</b></h3>
<p>C# 2.0是一次完善和补充，也是一次变革与重生。在2.0中引入了诸多的语言特性，完善了1.0基础上的某些不足，例如匿名方法将代码放在委托而无需创建新的方法；可空类型实现了对值类型的null操作；而部分类将一个类分解到多个类文件中。这些补充和完善， 总结起来主要包括：</p>
<ul>
<li>匿名方法 </li>
<li>可空类型 </li>
<li>部分类 </li>
<li>迭代器 </li>
<li>泛型 </li>
</ul>
<p>其中，泛型支持是C# 2.0的重中之重，.NET框架从CLR级别实现了对泛型的支持，提供专门的IL指令支持泛型操作，同时配合C#语言机制构造一种全新的编程结构，实现了对类型抽象化的通用处理方式，这就是算法重用。</p>
<p>以最简单的交换数据为例，我们来了解泛型带来的好处：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code01, 2009/05/07
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">public static void </span>Swap(<span style="color: blue">ref int </span>x, <span style="color: blue">ref int </span>y)
{
    <span style="color: blue">int </span>temp = x;
    x = y;
    y = temp;
}

<span style="color: blue">public static void </span>Swap(<span style="color: blue">ref string </span>str1, <span style="color: blue">ref string </span>str2)
{
    <span style="color: blue">string </span>temp = str1;
    str1 = str2;
    str2 = temp;
}</pre>
</div>
<p>以上两种算法分别实现了对整型、字符串型数据的交换，在泛型引入之前实现相同的交换算法需要分别为所有的类型构建相似的处理逻辑，这显然是一种代码上的浪费，而泛型特性彻底解决了这一问题：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code02, 2009/05/07
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">public static void </span>Swap&lt;T&gt;(<span style="color: blue">ref </span>T t1, <span style="color: blue">ref </span>T t2)
{
    T temp = t1;
    t1 = t2;
    t2 = temp;
}</pre>
</div>
<p>对于不同的类型，在运行时以实际类型对T占位符进行替换，并转换为本地代码，彻底实现了灵活的类型抽象和算法重用。同时，除了代码级别的重用好处，泛型解决了类型转换、装箱与拆箱、类型安全等诸多问题，为程序设计带来巨大的变革。</p>
<h3><b>3.0</b><b>，涅槃与重生</b></h3>
<p>C# 3.0是语言发展历史上的里程碑变革，就像凤凰涅槃一般为C#语言注入强大编程体验和活力，简洁、干净、富有意义，这些特性中主要包括：</p>
<ul>
<li>匿名类型 </li>
<li>自动属性 </li>
<li>对象初始化器 </li>
<li>集合初始化器 </li>
<li>隐式类型变量和隐式类型数组 </li>
<li>扩展方法 </li>
<li>查询表达式 </li>
</ul>
<p>除此之外，C# 3.0的最大亮点就是LINQ（Language Integrated Query，语言集成查询），在CLR中集成类似于SQL式的数据查询能力，一种前所未有的函数式编程体验在面向对象语言中得以大展拳脚，这不得不说是C#带来的超酷体验。</p>
<p>因为，本文并非一本讲述编程的教科书，所以我们无法在有限的篇幅来展现优雅的代码，只能取一瓢饮之，并通过简要的对比来领略3.0中的强大功能。以对象初始化器为例，在2.0时初始化对象成员，我们以这种方式实现：</p>
<div class="wp_codebox">
<pre><span style="color: #2b91af">User </span>user = <span style="color: blue">new </span><span style="color: #2b91af">User</span>();
user.Name = <span style="color: #a31515">"小王"</span>;
user.Age = 28;</pre>
</div>
<p>在3.0中，实现对象初始化有了更好的解决方案，由对象初始化器来完成：</p>
<div class="wp_codebox">
<pre><span style="color: #2b91af">User </span>user = <span style="color: blue">new </span><span style="color: #2b91af">User </span>{ Name = <span style="color: #a31515">"小王"</span>, Age = 28 };</pre>
</div>
<p>同样的方式可以用来实现集合的初始化和隐式类型的初始化等。</p>
<p>接着，我们再来了解一下自动属性带来的语法魅力，在3.0之前进行属性封装的是一件麻烦的事情，例如：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code03, 2009/05/07
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">class </span><span style="color: #2b91af">User
</span>{
    <span style="color: blue">private string </span>name;
    <span style="color: blue">public string </span>Name
    {
        <span style="color: blue">get </span>{ <span style="color: blue">return </span>name; }
    }

    <span style="color: blue">private int </span>age;
    <span style="color: blue">public int </span>Age
    {
        <span style="color: blue">get </span>{ <span style="color: blue">return </span>age; }
        <span style="color: blue">set </span>{ age = <span style="color: blue">value</span>; }
    }
}</pre>
</div>
<p>而自动属性将这一切化简为无形，语法简单而功能依旧：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code04, 2009/05/07
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">public class </span><span style="color: #2b91af">User
</span>{
    <span style="color: blue">public string </span>Name { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }
    <span style="color: blue">public int </span>Age { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }
}</pre>
</div>
<p>这些所有的新特性最终都为了一个共同的目标而铺垫，这就是C# 3.0中最重量级的新特性：LINQ。所以，本文也不能少了对LINQ的讨论，在代码级别实现类似于SQL式的查询语法，以类型安全的通用方式完成增、删、改、查等数据操作的基本方式。只要数据源基于IEnumerable&lt;T&gt;接口而实现，那么不管是关系型数据、内存中集合还是XML都可以作为LINQ查询对象进行数据处理，这为面向对象语言实现函数式的编程体验创造了条件，一种全新的编程风格为编程体验刮来一股旋风：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code05, 2009/05/07
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">public static void </span>Main()
{
    <span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">User</span>&gt; users = <span style="color: blue">new </span><span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">User</span>&gt;
    {
        <span style="color: blue">new </span><span style="color: #2b91af">User</span>{Name = <span style="color: #a31515">"小王"</span>, Age = 27},
        <span style="color: blue">new </span><span style="color: #2b91af">User</span>{Name = <span style="color: #a31515">"小张"</span>, Age = 29},
        <span style="color: blue">new </span><span style="color: #2b91af">User</span>{Name = <span style="color: #a31515">"小李"</span>, Age = 23}
    };

    <span style="color: #2b91af">IEnumerable</span>&lt;<span style="color: #2b91af">User</span>&gt; result = <span style="color: blue">from </span>user <span style="color: blue">in </span>users
                               <span style="color: blue">where </span>user.Age &lt; 30
                               <span style="color: blue">orderby </span>user.Age <span style="color: blue">descending
                               select </span>user;

    <span style="color: blue">foreach </span>(<span style="color: blue">var </span>user <span style="color: blue">in </span>result)
    {
        <span style="color: green">//执行操作
    </span>}
}</pre>
</div>
<p>你看，这种体验果然非同凡响，优雅而简单没有辜负Anders对于代码美学的追求。而作为编程用户，我们同样体味了这种理念在功能和结构上的双重精彩。</p>
<h2>&nbsp;</h2>
<h3>参考文献</h3>
<p>（Web）<a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html">http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html</a></p>
<p>（Web）<a href="http://weblogs.asp.net/podwysocki/archive/2008/05/24/what-is-the-future-of-c-anyways.aspx">http://weblogs.asp.net/podwysocki/archive/2008/05/24/what-is-the-future-of-c-anyways.aspx</a></p>
<p>（Web）New features in C# 4.0</p>
<p>（Web）<a href="http://msdn.microsoft.com/en-us/magazine/cc163340.aspx">http://msdn.microsoft.com/en-us/magazine/cc163340.aspx</a></p>
<p><b>作者简介：</b></p>
<p>王涛，网名Anytao，微软C# MVP，高级软件工程师，机械工程硕士，《你必须知道的.NET》一书作者，主要研究方向为.NET底层架构和企业级系统应用。现就职于某软件公司负责架构设计、软件开发和项目管理方面的工作。作者对.NET基础架构和CLR底层运行机制有浓厚的研究兴趣和造诣，熟悉ASP.NET、XML、WCF、SQL Server相关技术，对面向对象、设计模式和软件架构有一定的研究与实践经验。他的联系方式如下：<a href="/Anytao">http://www.cnblogs.com/Anytao</a></p>
<p>&nbsp;</p>
<div class="wp_codebox">
<pre>更多精彩，尽在<a target="_blank" href="http://anytao.net/blog">anytao.net</a></pre>
</div>
<p>&nbsp;</p>
<div id="MySignature">
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/05/08 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a> | <a href="http://anytao.net/blog/post/2009/05/07/anytao-insidenet-29-tenyear-part01.aspx" title="http://anytao.net/blog/post/2009/05/07/anytao-insidenet-29-tenyear-part01.aspx">http://anytao.net/blog/post/2009/05/08/anytao-insidenet-29-tenyear-part01.aspx</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</p>
</div><img src ="http://www.cnblogs.com/anytao/aggbug/1452310.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47995/" target="_blank">Google Voice 上手</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[一步一步MVC]第五回：让TagBuilder丰富你的HtmlHelper</title><link>http://www.cnblogs.com/anytao/archive/2009/05/06/anytao-mvc-05-tagbuilderforhtmlhelper.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Tue, 05 May 2009 16:41:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/05/06/anytao-mvc-05-tagbuilderforhtmlhelper.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1450340.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/05/06/anytao-mvc-05-tagbuilderforhtmlhelper.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1450340.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1450340.html</trackback:ping><description><![CDATA[<p><strong><a target="_blank" href="http://anytao.net/">anytao.net</a> | <a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a>&nbsp; </span></strong></p>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.05.06 作者：</span><a href="http://about.anytao.com/"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，Anytao原创作品，转贴请注明作者和出处。</span></p>
<p>对HtmlHelper进行扩展，是MVC中对于View层进行灵活控制的主要手段之一，对此我在<a href="http://anytao.net/blog/post/2009/04/29/anytao-mvc-07-actionlinktalk.aspx">第七回：漫谈ActionLink，有时&ldquo;胡搅蛮缠&rdquo;</a>中进行过探讨。在本文，只是一个小技巧，丰富我们在自定义HtmlHelper时可以有更好的选择。</p>
<p>首先，我们先了解一下，几个简单的HtmlHelper扩展是如何实现：</p>
<div class="wp_codebox">
<pre><span style="color: blue">public static string </span>Label(<span style="color: blue">this </span><span style="color: #2b91af">HtmlHelper </span>helper, <span style="color: blue">string </span>name, <span style="color: blue">string </span>value)
{
    <span style="color: blue">return string</span>.Format(<span style="color: #a31515">"&lt;label for='{0}'&gt;{1}&lt;/label&gt;&lt;br /&gt;"</span>, name, value);
}</pre>
</div>
<p>很简单，就是实现一个对HtmlHelper的扩展方法，这样我们就可以在View层通过</p>
<div class="wp_codebox" style="width: 559px; height: 31px;">
<pre><span>&lt;%</span><span style="color: blue">= </span>Html.Label(<span style="color: #a31515">"Anytao"</span>, <span style="color: #a31515">"tao"</span>) <span>%&gt;</span></pre>
</div>
<p>而无需：</p>
<div class="wp_codebox">
<pre><span style="color: blue">&lt;</span><span style="color: #a31515">label </span><span style="color: red">for</span><span style="color: blue">="tao"&gt;</span>Anytao<span style="color: blue">&lt;/</span><span style="color: #a31515">label</span><span style="color: blue">&gt;</span></pre>
</div>
<p>显然，通过Html.Lable方式更加的简洁和灵活，此例仅仅是个简单的举例。事实上，通过Html.XXX可以封装更多的预定义Html代码，实现更多有效、复杂的个性化实现，例如在本文的下一篇我将通过Html.Naviagte方式实现一个封装了Sitemap的Breadcrumb控制，从而使得我们体会更好的Html是如何做到的。</p>
<p>对于Html.Label而言，还有一个重要的内容需要添加，那就是对于Html标记如何动态的指定和渲染，例如我们可以对Label指定id、class还有更多其他的Html属性，这是个有市场的需求，因为至少为Dom元素指定Css是经常发生的事情，例如假设有如下的需求：</p>
<div class="wp_codebox">
<pre><span style="color: blue">&lt;</span><span style="color: #a31515">label </span><span style="color: red">class</span><span style="color: blue">="grey" </span><span style="color: red">for</span><span style="color: blue">="tao"&gt;</span>Anytao<span style="color: blue">&lt;/</span><span style="color: #a31515">label</span><span style="color: blue">&gt;</span></pre>
</div>
<p>在原有的Html.Label扩展实现中，class的指定是无法做到的，因此需要从新构造，办法就是添加htmlAttributes参数，实现类似于ActionLink一样的控制，例如：</p>
<div class="wp_codebox">
<pre><span>&lt;%</span><span style="color: blue">= </span>Html.Label(<span style="color: #a31515">"Anytao"</span>, <span style="color: #a31515">"tao"</span>, <span style="color: blue">new </span>{ @class=<span style="color: #a31515">"grey"</span>} <span>%&gt;</span></pre>
</div>
<p>那么，我们该如何办呢？我想起了TagBuilder，来简化实现的复杂度，事实上TagBuilder就是干这个的主，废话不说给出更新之后的Html.Label实现：</p>
<div class="wp_codebox">
<pre><span style="color: blue">public static string </span>Label(<span style="color: blue">this </span><span style="color: #2b91af">HtmlHelper </span>helper, <span style="color: blue">string </span>name, <span style="color: blue">string </span>value, <span style="color: blue">object </span>htmlAttributes)
{
    <span style="color: #2b91af">TagBuilder </span>tagBuilder = <span style="color: blue">new </span><span style="color: #2b91af">TagBuilder</span>(<span style="color: #a31515">"label"</span>)
    {
        InnerHtml = value
    };
    tagBuilder.MergeAttribute(<span style="color: #a31515">"for"</span>, name);
    tagBuilder.MergeAttributes(<span style="color: blue">new </span><span style="color: #2b91af">RouteValueDictionary</span>(htmlAttributes));
    <span style="color: blue">return </span>tagBuilder.ToString(<span style="color: #2b91af">TagRenderMode</span>.Normal);
}</pre>
</div>
<p>办法很简单，在Html.Label内部通过TagBuilder，实现了对htmlAttribute特性的添加，实现的办法非常简单：</p>
<div class="wp_codebox">
<pre>tagBuilder.MergeAttributes(<span style="color: blue">new </span><span style="color: #2b91af">RouteValueDictionary</span>(htmlAttributes));</pre>
</div>
<p>在MergeAttributes方法内部实现对Html Attribute信息的整合，有兴趣大家可以了解具体的实现规则。</p>
<p>既然我们的主角是TagBuilder，那么就顺便近看其面目，总体来说TagBuilder就是创建Html标签的Builder，类似于StringBuilder封装了对Html标签的很多简单而有效的方法（例如MergeAttributes），主要包括：</p>
<ul>
<li>AddCssClass </li>
<li>GenerateId </li>
<li>MergeAttribute </li>
<li>SetInnerText </li>
<li>ToString </li>
</ul>
<p>还包括几个属性：</p>
<ul>
<li>Attributes </li>
<li>IdAttributeDotReplacement </li>
<li>InnerHtml </li>
<li>TagName </li>
</ul>
<p>工欲善其事，必先利其器。TagBuidler使得HtmlHelper变得简单，自信的观众可以完全不用TagBuilder，通过任何其他的办法来实现类似于MergeAttribute、AddCssClass这样的逻辑，但是既然已经有了，不妨一试。就像它的大哥StringBuilder，给我们处理string带来多少不错的亲近感受，看面子也不妨关照一下小弟TagBuilder。</p>
<p>&nbsp;</p>
<div class="wp_codebox">
<pre>更多精彩，尽在<a target="_blank" href="http://anytao.net/blog">anytao.net</a></pre>
</div>
<p>&nbsp;</p>
<div id="MySignature">
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/05/06 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a> | <a href="http://anytao.net/blog/post/2009/05/05/anytao-mvc-08-tagbuilderforhtmlhelper.aspx" title="http://anytao.net/blog/post/2009/05/05/anytao-mvc-08-tagbuilderforhtmlhelper.aspx">http://anytao.net/blog/post/2009/05/05/anytao-mvc-08-tagbuilderforhtmlhelper.aspx</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</p>
</div><img src ="http://www.cnblogs.com/anytao/aggbug/1450340.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47994/" target="_blank">Google号召社区力量为互联网加速</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[一步一步MVC]第四回：漫谈ActionLink，有时“胡搅蛮缠”</title><link>http://www.cnblogs.com/anytao/archive/2009/04/30/anytao-mvc-04-actionlinktalk.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Wed, 29 Apr 2009 17:21:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/04/30/anytao-mvc-04-actionlinktalk.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1446639.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/04/30/anytao-mvc-04-actionlinktalk.html#Feedback</comments><slash:comments>26</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1446639.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1446639.html</trackback:ping><description><![CDATA[<p><strong><a target="_blank" href="http://anytao.net/">anytao.net</a> | <a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a>&nbsp; </span></strong></p>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.04.30 作者：</span><a href="http://about.anytao.com/"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，Anytao原创作品，转贴请注明作者和出处。</span></p>
<p>MVC时代来临了，但是一开始是不被很多人接受的。可能的主要原因是，大家不得不告别拖拉控件的至爽感受，回到貌似asp的历史岁月。所以，心有不甘是可以理解的，然而时代显然是进步的。我们虽然必须在View中进行很多HTML代码的工作，但是MVC为我们提供了可以堪称完美的方案（至少我是这样认为的），那就是HtmlHelper。在MVC的View层，我们有很多熟悉的面孔，例如Html.Encode、Html.AntiForgeryToken、Html.BeginForm、Html.TextBox等，而其中ActionLink算是其中的&ldquo;猛将兄&rdquo;。</p>
<h2>浅议HtmlHelper</h2>
<p>简单的说，HtmlHelper就是一个封装了ViewContext、IViewDataContainer、RouteCollection等上下文信息的一箩筐静态方法类（注，HtmlHelper本身并不是静态类），其中包含了我们上文介绍的熟悉身影Encode、AntiForgeryToken等，但不包含BeginForm、TextBox，当然也不包括ActionLink，其原因是BeginForm、TextBox、ActionLink其实是HtmlHelper的扩展方法，我们可以从智能感知提示中最直观的得到了解：</p>
<p><a href="/anytao/admin/$o_anytao_mvc_07_actionlinktalk_01[1][3].png"><img height="264" width="504" src="http://images.cnblogs.com/cnblogs_com/anytao/186609/o_anytao_mvc_07_actionlinktalk_01.png" alt="o_anytao_mvc_07_actionlinktalk_01[1]" border="0" title="o_anytao_mvc_07_actionlinktalk_01[1]" style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" /></a> </p>
<p>显然，ActionLink和Encode的智能提示标记是有区别的。</p>
<p>所以，HtmlHelper其实很简单，而通过Extension Methods对其的&ldquo;功能注入&rdquo;机制实现了极大的扩展空间。而且，HtmlHelper封装了ViewContext、RouteCollection等上下文信息，为实现扩展带来便利。所以，顺便提一下，这也正是<a href="/JeffreyZhao">老赵</a>同志在<a href="/JeffreyZhao/archive/2009/04/29/custom-view-helpers-1.html">为视图自定义辅助方法（上）</a>中实现JQueryHelper时引入相应元素（ViewContext、RouteCollection、ViewPage），有着异曲同工之妙，所以HtmlHelper并不是唯一的选择，高兴的话，你也可以类似于AnytaoHelper之类的东东。</p>
<p>所以，通过HtmlHelper就可在运行时动态生成HTML代码，其实我们在WebForm时代就经常玩儿这种&ldquo;阴招&rdquo;，然而在HtmlHelper这里，显然已经发扬光大了。例如老赵的JQueryHelper就通过一系列的包装，省去了对validation的麻烦语法。</p>
<p>同时，扩展HtmlHelper其实及其简单。例如：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code01, 2009/04/30
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">public static string </span>Label(<span style="color: blue">this </span>HtmlHelper helper, <span style="color: blue">string </span>name, <span style="color: blue">string </span>value)
{
    <span style="color: blue">return string</span>.Format(<span style="color: #a31515">"&lt;label for='{0}'&gt;{1}&lt;/label&gt;&lt;br /&gt;"</span>, name, value);
}</pre>
</div>
<p>通过下面的方式就可以调用该方法了：</p>
<div class="wp_codebox">
<pre><span>&lt;%</span><span style="color: blue">= </span>Html.Label(<span style="color: #a31515">"name"</span>, <span style="color: #a31515">"Tao"</span>) <span>%&gt;</span></pre>
<pre><span>同样的道理，当我们摊开ActionLink的实现具体实现时，可见：</span></pre>
<div class="wp_codebox">
<pre><span style="color: blue">public static string </span>ActionLink(<span style="color: blue">this </span><span style="color: #2b91af">AjaxHelper </span>ajaxHelper, <span style="color: blue">string </span>linkText, <span style="color: blue">string </span>actionName, <span style="color: blue">string </span>controllerName, <span style="color: #2b91af">RouteValueDictionary </span>routeValues, <span style="color: #2b91af">AjaxOptions </span>ajaxOptions, <span style="color: #2b91af">IDictionary</span>&lt;<span style="color: blue">string</span>, <span style="color: blue">object</span>&gt; htmlAttributes) {
    <span style="color: blue">if </span>(<span style="color: #2b91af">String</span>.IsNullOrEmpty(linkText)) {
        <span style="color: blue">throw new </span><span style="color: #2b91af">ArgumentException</span>(<span style="color: #2b91af">MvcResources</span>.Common_NullOrEmpty, <span style="color: #a31515">"linkText"</span>);
    }

    <span style="color: blue">string </span>targetUrl = <span style="color: #2b91af">UrlHelper</span>.GenerateUrl(<span style="color: blue">null</span>, actionName, controllerName, routeValues, ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, <span style="color: blue">true </span><span style="color: green">/* includeImplicitMvcValues */</span>);

    <span style="color: blue">return </span>GenerateLink(linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes);
}</pre>
</div>
<span style="font-family: Courier New;">ActionLink其实根据Action、Controller、linkText信息，通过GenerateLink生成了我们需要的HTML代码，我们将在下面继续看到影响GenerateLink的还有Route信息。</span></div>
<h2>有时&ldquo;胡搅蛮缠&rdquo;</h2>
<p>聊了半天HtmlHelper，该说说ActionLink了。正如前文而言，ActionLink仅仅是HtmlHelper的扩展方法而已。不过，虽然ActionLink平易近人，但是还是在不经意间发现其胡搅蛮缠的地方。我们先按下不表来看看如何使用ActionLinks，MVC Framework为我们提供了两种方式：</p>
<ul>
<li>ActionLink </li>
<li>ActionLink&lt;TController&gt; </li>
</ul>
<p>显而易见，一种是非泛型方法，通过参数方式调用，没有强类型优势；另一种是泛型方法，可以通过强类型调用，不过如果通过ActionName对Action进行重写标记时，泛型ActionLink&lt;TController&gt;是不可用的，我在《<a href="http://anytao.net/blog/post/2009/04/23/anytao-mvc-05-actionauthorize.aspx">还是ActionFilter，实现对业务逻辑的统一Authorize处理</a>》已进行过讨论了。</p>
<div class="wp_codebox">
<div class="wp_codebox">
<pre><span>&lt;%</span><span style="color: blue">=</span>Html.ActionLink(<span style="color: #a31515">"Edit"</span>, <span style="color: #a31515">"Edit"</span>, <span style="color: #a31515">"Book"</span>, <span style="color: blue">new </span>{ id = Model.ID }, <span style="color: blue">new </span>{ @class = <span style="color: #a31515">"BookDetail"</span>})<span>%&gt;</span></pre>
</div>
</div>
<p>&nbsp;</p>
<p>具体而言，上述参数主要包括：</p>
<ul>
<li>Edit，为linkText，具体而言就是显示的字符串； </li>
<li>Edit，对应为ActionName； </li>
<li>Book，为Controller； </li>
<li>new { id = Model.ID }，为生成元素的id定义； </li>
<li>new { @class = &ldquo;BookDetail&rdquo; }，则为元素添加了tag要素。 </li>
</ul>
<p>具体的执行逻辑不是我们关心的问题，而上述代码生成的Source Code，则对应为：</p>
<div class="wp_codebox">
<pre><span style="color: blue">&lt;</span><span style="color: #a31515">a </span><span style="color: red">class</span><span style="color: blue">="BookDetail" </span><span style="color: red">href</span><span style="color: blue">="/Book/Edit/1"&gt;</span>Edit<span style="color: blue">&lt;/</span><span style="color: #a31515">a</span><span style="color: blue">&gt;</span></pre>
</div>
<p>而如果应用泛型ActionLink，则上述调用将变成：</p>
<div class="wp_codebox">
<pre><span>&lt;%</span><span style="color: blue">= </span>Html.ActionLink&lt;<span style="color: #2b91af">BookController</span>&gt;(c =&gt; c.Detail(), <span style="color: #a31515">"Edit"</span>) <span>%&gt;</span></pre>
</div>
<p>生成同样的Source Code，不过通常情况下，我们还是推荐泛型ActionLink，至少有类型安全、代码优雅的优点。</p>
<p>注：既然是ActionLink，文如其名，我们不能将其滥用，也就是说涉及Action的Links时可以考虑用ActionLink，其他情况下最好还是手写自己的链接代码或者扩展自己的HtmlHelper等。</p>
<p>然而，在有些情况下，假设我们有如下Route：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code02, 2009/04/30
// Author  : Anytao, http://www.anytao.com
</span>routes.MapRoute(
    <span style="color: #a31515">"BookRoute"</span>,
    <span style="color: #a31515">"Tao/Book/id"</span>,
    <span style="color: blue">new </span>{ controller = <span style="color: #a31515">"Book"</span>, action = <span style="color: #a31515">"Detail"</span>, id = <span style="color: #a31515">"" </span>}
    );</pre>
</div>
<p>当我们使用</p>
<div class="wp_codebox">
<pre><span>&lt;%</span><span style="color: blue">= </span>Html.ActionLink(<span style="color: #a31515">"Book"</span>, <span style="color: #a31515">"Detail"</span>, <span style="color: #a31515">"Book"</span>, <span style="color: blue">null</span>, <span style="color: blue">null</span>) <span>%&gt;</span></pre>
</div>
<p>调用BookController下的Detail Action，不过令我们奇怪的是，生成Html代码并不如期望的那样，而是：</p>
<div class="wp_codebox">
<pre><span style="color: blue">&lt;</span><span style="color: #a31515">a </span><span style="color: red">href</span><span style="color: blue">="/Tao/Book/id"&gt;</span>Book<span style="color: blue">&lt;/</span><span style="color: #a31515">a</span><span style="color: blue">&gt;</span></pre>
</div>
<p>显然，ActionLink有点儿&ldquo;胡搅蛮缠&rdquo;了。其原因在于，新定义的BookRoute改写了ActionLink的&ldquo;既有&rdquo;行为，本来我们期望的是：</p>
<div class="wp_codebox">
<pre><span style="color: blue">&lt;</span><span style="color: #a31515">a </span><span style="color: red">href</span><span style="color: blue">="/Book/Detail/id"&gt;</span>Book<span style="color: blue">&lt;/</span><span style="color: #a31515">a</span><span style="color: blue">&gt;</span></pre>
</div>
<p>为了追查原因，我们将对ActionLink进行了必要的调查，首先了解ActionLink的定义：</p>
<div class="wp_codebox">
<pre><span style="color: blue">public static string </span>ActionLink(<span style="color: blue">this </span><span style="color: #2b91af">HtmlHelper </span>htmlHelper, <span style="color: blue">string </span>linkText, <span style="color: blue">string </span>actionName)</pre>
</div>
<p>而ActionLink的具体实现中，我们看到了routeCollection的GetVirtualPath方法中涉及了对<a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Collections.Generic.Dictionary&lt;,&gt;">"&gt;"&gt;Dictionary</a>&lt;<a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.String">string</a>, <a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web.Routing:3.5.0.0:31bf3856ad364e35/System.Web.Routing.RouteBase">RouteBase</a>&gt;的操作，所以不言而喻，ActionLink生成的Url是受routeCollection影响的。对于其&ldquo;胡搅蛮缠&rdquo;，我相信这就是原因吧。</p>
<p>所以，虽是一个小小的意外，但是了解了就不是意外。对于我们的应用而言，有两点值得注意：</p>
<ul>
<li>注意Route定义对于ActionLink可能造成的影响。 </li>
<li>在这种情况下，我们可以考虑放弃ActionLink，而通过全手动方式实现： </li>
</ul>
<div class="wp_codebox">
<pre><span style="color: blue">&lt;</span><span style="color: #a31515">a </span><span style="color: red">href</span><span style="color: blue">="Book/Detail/</span><span>&lt;%</span>= Model.ID <span>%&gt;</span><span style="color: blue">"&gt;</span>Book<span style="color: blue">&lt;/</span><span style="color: #a31515">a</span><span style="color: blue">&gt;</span></pre>
</div>
<p>不偿为一种回归原始的方式，不是吗？</p>
<p>&nbsp;</p>
<p>本文调侃了题目，但是更重要的事情是我们对HtmlHelper及ActionLink有了个大致的了解，对于更好的应用是有好处的。那么，今天就说到这里。</p>
<p>&nbsp;</p>
<div class="wp_codebox">
<pre>代码下载，<a href="http://files.cnblogs.com/anytao/anytao_mvc_ActionLinkWalkthrough.rar">这里</a>。更多关注，尽在<a href="http://anytao.net/blog">anytao.net/blog</a></pre>
</div>
<p>&nbsp; </p>
<div id="MySignature">
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/04/30 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a> | <a href="http://anytao.net/blog/post/2009/04/29/anytao-mvc-07-actionlinktalk.aspx" title="http://anytao.net/blog/post/2009/04/29/anytao-mvc-07-actionlinktalk.aspx">http://anytao.net/blog/post/2009/04/29/anytao-mvc-07-actionlinktalk.aspx</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</p>
</div><img src ="http://www.cnblogs.com/anytao/aggbug/1446639.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47989/" target="_blank">Twitter无处不在 魔兽世界Twitter发送器插件发布</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[一步一步MVC]第三回：MVC范例大观园</title><link>http://www.cnblogs.com/anytao/archive/2009/04/29/anytao-mvc-03-mvcsamples.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Tue, 28 Apr 2009 16:07:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/04/29/anytao-mvc-03-mvcsamples.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1445789.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/04/29/anytao-mvc-03-mvcsamples.html#Feedback</comments><slash:comments>26</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1445789.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1445789.html</trackback:ping><description><![CDATA[<p><strong><a target="_blank" href="http://anytao.net/">anytao.net</a> | <a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a>&nbsp; </span></strong></p>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.04.29 作者：</span><a href="http://about.anytao.com/"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，Anytao原创作品，转贴请注明作者和出处。</span></p>
<p>MVC是个新鲜的东西，至少为ASP .NET Web世界带来或多或少的争议，褒奖者有之，诋毁者有之。这也正常，人类的思维确实没法统一，即便是多个选择其实是件好事儿也一样。不管怎样，评说者至少应该在了解的基础上再进行评论，才显得&ldquo;专业&rdquo;，没有品味的找茬型选手实在不值得恭维。</p>
<p>作为MVC范例集锦，我将MVC发布之后业界的应用开源项目做个简单的整理，<a href="http://anytao.cnblogs.com/">Anytao</a>不打算对任何项目发表个人观点，因为有些项目未经本人了解，所以此处仅是one by one式的陈列，期望对学习者有些帮助而已。</p>
<ul>
<li><a target="_blank" href="http://www.codeplex.com/nerddinner">NerdDinner</a> </li>
</ul>
<p>NerdDinner随着ScottGu、Phli几位大牛为作品《<a href="http://www.wrox.com/WileyCDA/WroxTitle/Professional-ASP-NET-MVC-1-0.productCd-0470384611.html"><em>Professional ASP.NET MVC 1.0</em></a>》谱写的辅助系统，同时通过一个在线系统<a href="http://www.nerddinner.com/" title="http://www.nerddinner.com/">http://www.nerddinner.com/</a>以生动的实例来展现MVC技术，NerdDinner示例贯穿全书，尤其是第一章的Walkthrough可以让我们对MVC有个初次了解。</p>
<ul>
<li><a target="_blank" href="http://www.asp.net/learn/mvc/tutorial-26-cs.aspx">Contact Management</a> </li>
</ul>
<p>该范例是asp.net/mvc的讲解实例，因为它太简单以至于没有什么好说的，初入MVC的同学可以关注一下，安装step by step的方式构建自己的Contact Management应用。</p>
<ul>
<li><a target="_blank" href="http://mvcsamples.codeplex.com/">MVC Storefront</a> </li>
</ul>
<p>不知为什么范例程序常常以Store来演示（例如Petshop），可能的原因是Store应用简单而全面，所以MVCStore应用也是这样一个简化示例， 我们可以研究研究。</p>
<ul>
<li><a target="_blank" href="http://www.codeplex.com/oxite">Oxite</a> </li>
</ul>
<p>业界对Oxite有<a target="_blank" href="http://onlyhujian.spaces.live.com/Blog/cns%21B45C4FBBFBBE1117%21526.entry?wa=wsignin1.0&amp;sa=918094551">不少批评</a>，<a href="http://blog.wekeroad.com/">Rob Conery</a>是最尖锐的一个，作为&ldquo;号称&rdquo;微软MVC范例的Oxite，虽有些细可圈可点，但是离微软官方范例的角度确实还有距离。园子的代震军发表的<a href="/daizhj/archive/2009/02/26/1398689.html">关于两个MVC示例的思考(MVCStore和Oxite)</a>，对此进行的讨论或许可以给您以思考，从应用角度而言Oxite其实并非一无是处，很多点上还是有不错的运用，例如关于ActionFilter和IoC的应用是值得参考的。</p>
<ul>
<li><a target="_blank" href="http://www.codeplex.com/Kigg">KIGG</a> </li>
</ul>
<p>Kigg是Codeplex上开源项目，从项目规模上而言，Kigg属于&ldquo;大块头&rdquo;，以MVC为基础架构，同时设计很多技术应用，单元测试也有不错可借鉴的地方。</p>
<ul>
<li><a target="_blank" href="http://www.codeplex.com/ezsocio">Ezsocio</a> </li>
</ul>
<p>Ezsocio至少可以是个范例，一套基于微软.NET平台的Social Network Software(SNS)系统，会用到许多最新开发技术，如ASP.NET MVC、LINQ、WCF、Unity、JQuery等，虽然还是个半成品，但是作为对于MVC学习和了解角度而言，还是&ldquo;够用的&rdquo;。例如以Unity为容器的IoC设计、JQuery在MVC的应用、Validation、Cryptography、Repository模式等，好了不做广告了，那只是个还没有完成的作品。</p>
<ul>
<li><a href="http://groups.google.com/group/sharp-architecture">sharp-architecture</a> </li>
</ul>
<p>Sharp-Architecture是MVC和NHibernate应用范例，作为号称&ldquo;Sharp Architecture&rdquo;的应用，我想一定可以为我们呈现不一样的设计，对于了解MVC和NHibernate的人或许是个不错的选择。</p>
<ul>
<li><a target="_blank" href="http://fubumvc.pbwiki.com/">fubumvc</a> </li>
</ul>
<p>fubumvc，可以看作是for us by us MVC，是老赵同志推荐给我的。fubumvc在了解ASP .NET MVC核心架构的基础上，表达了作者&ldquo;不同意&rdquo;ASP .NET MVC对于设计的理解，所以几个人凑在一起合谋了fubumvc Framework。<a href="http://stackoverflow.com/questions/416218/what-are-the-main-differences-between-asp-net-mvc-and-fubumvc">这里</a>，有一些关于FubuMVC和ASP .NET MVC的区别。</p>
<p>&nbsp;</p>
<p>既然是大观园，可能以后还有补充，谁有更好的分享也可以在留言提供给我，以方便大家&ldquo;有底放肆&rdquo;。至于品评和讨论，还是放在以后吧。</p>
<p>&nbsp;</p>
<div class="wp_codebox">
<pre>更多关注，尽在<a href="http://anytao.net/blog">anytao.net/blog</a></pre>
</div>
<p>&nbsp; </p>
<div id="MySignature">
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/04/29 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a> | <a href="http://anytao.net/blog/post/2009/04/28/anytao-mvc-06-mvcsamples.aspx" title="http://anytao.net/blog/post/2009/04/28/anytao-mvc-06-mvcsamples.aspx">http://anytao.net/blog/post/2009/04/28/anytao-mvc-06-mvcsamples.aspx</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</p>
</div><img src ="http://www.cnblogs.com/anytao/aggbug/1445789.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47988/" target="_blank">Firefox 3.5匆忙推出漏洞多 Mozilla本月将更新</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[推荐]一本关注P/Invoke的国产精品《精通.NET互操作：P/Invoke，C++ Interop和COM Interop》</title><link>http://www.cnblogs.com/anytao/archive/2009/04/23/anytao_recommand_book_pinvoke.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Thu, 23 Apr 2009 04:59:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/04/23/anytao_recommand_book_pinvoke.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1441967.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/04/23/anytao_recommand_book_pinvoke.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1441967.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1441967.html</trackback:ping><description><![CDATA[<p><strong><a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a>&nbsp; </span></strong></p>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.04.23 作者：</span><a href="http://about.anytao.com/"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，Anytao原创作品，转贴请注明作者和出处。</span></p>
<p>提起P/Inoke，我们不可避免的感受到一丝丝的&ldquo;高深&rdquo;。一般来说，高深不代表高不可攀，作为.NET平台下于非托管代码交互的基本方式，P/Inoke对大多数Web开发者是个不常光顾的场所，然而互操作问题是或多或少在我们的开发中不期而遇的问题，因为总会在某个偶然我们对托管世界和非托管世界建立一个交集。那么，了解和深入P/Invoke将是你不得不进行起航的拐点，今日我的朋友<a target="_blank" href="http://huangjizhou.cnblogs.com/">黄际洲</a>的新书《<a target="_blank" href="http://sites.google.com/site/netinterop/">精通.NET互操作：P/Invoke，C++ Interop和COM Interop</a>》一书提供了一个打开P/Invoke的钥匙，正像本书的定位一样：<a href="/huangjizhou/archive/2009/04/20/1439837.html">国内首本全面深入介绍.NET互操作技术</a>的技术书籍。</p>
<p>下面是关于本书的一些简单信息，感兴趣的同志可以拿来读一读，相信对此有很好的收获。首先来看看该书的长相：</p>
<p><img height="417" width="600" src="http://images.cnblogs.com/cnblogs_com/anytao/162192/o_book_jizhou_pinvoke.jpg" /> </p>
<ul>
<li>书号：978-7-115-20434-9 </li>
<li>作者：黄际洲&nbsp;&nbsp;&nbsp; 崔晓源 </li>
</ul>
<h2>本书的内容</h2>
<p>本书介绍Windows平台上的托管代码与非托管代码之间进行互操作的各种技术，包括由.NET提供的各种互操作方法、属性以及各种工具的用法及其工作原理。本书包括3部分，平台调用&mdash;&mdash;主要用于解决在托管代码中调用非托管程序设计语言编写的flat API（如Win32 API、C/C++风格的API等）的问题；C++ Interop&mdash;&mdash;技术专门用于解决托管代码与C++编写的非托管代码之间的互操作问题；COM Interop&mdash;&mdash;介绍了使用COM Interop解决在托管代码中调用COM组件，以及在COM中调用托管类型的问题。 <br />本书适合所有在开发过程中需要涉及到托管代码与非托管代码进行交互操作的.NET开发人员阅读使用。不论是开始学习.NET编程的开发人员，还是刚刚接触互操作的资深.NET开发人员，都能从本书中获益。</p>
<h2>本书的主要特色</h2>
<ul>
<li>国内首本全面深入介绍.NET互操作技术的参考手册 </li>
<li>系统地介绍针对各种.NET互操作问题的解决方案 </li>
<li>帮助读者掌握.NET互操作过程中的最佳实践 </li>
</ul>
<h2>专家评论</h2>
<p>仅则其一二，更多评论请关注相关链接。</p>
<p>托管代码与非托管代码之间的交互是许多程序员在.NET开发平台上不得不面对的任务。《精通.NET互操作性：PInvoke, C++ Interop和COM Interop》这本书深入而透彻地解析了.NET支持的三种与原生代码互操作的技术，作者以自己的经验讲述了原生代码与托管代码之间互操作所涉及到的编程要点，以及背后的一些实现原理。书中提供的实例有助于程序员快速领会并掌握.NET与原生代码互操作技术的用法。我建议在.NET平台上工作的程序员读一读这本书。 </p>
<p>&mdash;&mdash;潘爱民（著名技术作家，著写了《COM原理与应用》等多部畅销书，并翻译了多部经典名作，如《深入解析Windows操作系统》（第四版）、《C++ Primer中文版》（第三版）、《COM本质论》、《计算机网络》（第四版）等。他现在微软亚洲研究院从事系统与安全方向的研究工作）</p>
<p>.NET平台是个托管的世界，提供了与以往完全不同的编程模型。毋庸置疑，.NET是当前及未来Windows平台下开发技术的主流。但转到.NET平台并非意味着使用.NET将现有的C/C++/COM代码进行重写。.NET提供的丰富互操作技术使开发人员能够通过这些技术将.NET代码与非托管代码进行集成，以重用现有非托管代码。可惜的是，市场上大部分.NET书籍对互操作技术少有涉足，中文资源尤其缺乏。本书深入且详尽地介绍了如何在托管代码与非托管代码之间进行互操作，涉及到了互操作技术的各个方面，是本非常有价值的参考书，高度推荐！ </p>
<p>&mdash;&mdash;金雪根（2002～2005年微软最有价值专家（MVP），CSDN技术论坛.NET版大版主（网名Saucer（思归））。《.NET企业服务框架&mdash;&mdash;应用.NET企业服务开发分布式业务解决方案》的译者之一） </p>
<p>微软发布了.NET Framework框架，这并不意味着要抛弃一切旧的技术，那些长期积累下来的非托管代码编写的东西，经过实践的检验，曾经带来过巨大的价值。将这些原有的代码转换成托管代码是不现实的，如何在托管代码与非托管代码之间进行互操作，继续使用原有的代码，本书给出了详细的解答。本书阐述了托管代码与非托管代码进行交互操作的主要技术，既有理论，又有详细的例子。相信读者通过阅读本书，能够全面掌握.NET互操作性这一技术的。</p>
<p>&mdash;&mdash; 孟宪会（2002-2008年微软最有价值专家（MVP），微软中文技术论坛版主，CSDN技术论坛.NET及Web开发版大版主（网名 net_lover（孟子E章）），《ASP.NET 2.0应用开发技术》作者，《Eric Meyer谈CSS（卷1）（卷2）》译者） </p>
<h2>关于更多</h2>
<p>关于本书已经有很多的赞誉，也无需我再次捧场，如果想要了解更多关于 的内容，可以参考以下地址，你会收获更多：</p>
<ul>
<li><a href="http://www.interop123.com">www.interop123.com</a></li>
<li><a href="/huangjizhou/archive/2009/04/20/1439837.html" title="http://www.cnblogs.com/huangjizhou/archive/2009/04/20/1439837.html">http://www.cnblogs.com/huangjizhou/archive/2009/04/20/1439837.html</a> </li>
</ul>
<p>更多的内容、更多的介绍还有更多的推荐，都可以从上获取。</p>
<pre>更多关注，尽在<a href="http://anytao.net/blog">anytao.net/blog</a></pre>
<div id="MySignature">
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/04/23 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a> | <a href="http://anytao.net/blog/post/2009/04/23/anytao-recommand-01-pinvokebook.aspx" title="http://anytao.net/blog/post/2009/04/23/anytao-recommand-01-pinvokebook.aspx">http://anytao.net/blog/post/2009/04/23/anytao-recommand-01-pinvokebook.aspx</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</p>
</div><img src ="http://www.cnblogs.com/anytao/aggbug/1441967.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47987/" target="_blank">预测：Twitter最可能收购的十家公司</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[一步一步MVC]第二回：还是ActionFilter，实现对业务逻辑的统一Authorize处理</title><link>http://www.cnblogs.com/anytao/archive/2009/04/23/anytao-mvc-02-actionauthorize.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Wed, 22 Apr 2009 17:20:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/04/23/anytao-mvc-02-actionauthorize.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1441706.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/04/23/anytao-mvc-02-actionauthorize.html#Feedback</comments><slash:comments>24</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1441706.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1441706.html</trackback:ping><description><![CDATA[<p><strong><a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a> | <a href="http://anytao.net/">anytao.net</a></span></strong></p>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.04.23&nbsp; 作者：</span><a href="http://about.anytao.com/"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，Anytao原创作品，转贴请注明作者和出处。</span></p>
<p>&nbsp;</p>
<h2>由问题引出</h2>
<p>在ASP .NET MVC中，以友好的URL访问资源是MVC吸引眼球的特色之一，但是随之而来对于Authorize问题的处理变得令人令人头痛。例如假设我们有一个获取Book信息的Action，定义在BookController中：</p>
<div class="wp_codebox">
<pre><span style="color: blue">public class </span><span style="color: #2b91af">BookController </span>: <span style="color: #2b91af">Controller
</span>{
    <span style="color: green">// Release : code01, 2009/04/22                    
    // Author  : Anytao, http://www.anytao.com
    </span><span style="color: blue">public </span><span style="color: #2b91af">ActionResult </span>Index(<span style="color: blue">int </span>id)
    {
        <span style="color: #2b91af">Book </span>model = (<span style="color: blue">new </span><span style="color: #2b91af">IBookService</span>()).GetBook(id);

        <span style="color: blue">return </span>View(model);
    }
}</pre>
</div>
<p>那么，我们可以通过<a href="http://anytao.net/Book/index/1">http://anytao.net/Book/index/1</a>，来访问id为1的Book（例如该书是《<a href="http://book.anytao.com/">你必须知道的.NET</a>》，哈哈，广告嫌疑）。在没有任何特别处理的情况下，对于该书的访问是&ldquo;不设防&rdquo;的。任何用户可以通过<a href="http://anytao.net/Book/index/1">http://anytao.net/Book/index/1</a>实现对《<a href="http://book.anytao.com/">你必须知道的.NET</a>》信息的访问。那么访问的资源如果是<a href="http://anytao.net/Secret/index/1">http://anytao.net/Secret/index/1</a>，显然我的秘密无一例外的对外公开了。</p>
<p>言之此处，我们的问题已经明白无疑，那么应该如何处理呢？我们可以很容易的想到通过以下的方式进行处理：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code02, 2009/04/22                    
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">public </span><span style="color: #2b91af">ActionResult </span>Index(<span style="color: blue">int </span>id)
{
    <span style="color: blue">if </span>(<span style="color: blue">new </span><span style="color: #2b91af">IAuthorizeService</span>().IsBookAuthorized(id, User.Identity.Name))
    {
        <span style="color: #2b91af">Book </span>model = (<span style="color: blue">new </span><span style="color: #2b91af">IBookService</span>()).GetBook(id);

        <span style="color: blue">return </span>View(model);
    }
    <span style="color: blue">else
    </span>{
        <span style="color: blue">return </span>View(<span style="color: #a31515">"NotValid"</span>);
    }
}</pre>
</div>
<p>显然，我通过IsBookAuthorized对GetBook服务的访问有效性进行控制，通过User的Name在数据库或者其他资源存储进行查找， 然后根据IsBookAuthorized结果进行是否访问的控制，显然不合法的用户将被导航到NotValid页，提示你是非法用户。</p>
<p>这种方式显然是最容易想到的办法，而且也广泛存在于我们实际的应用中，例如<a href="http://www.nerddinner.com/">NerdDinner</a>范例中也是通过这种方式进行Authorize控制处理的，例如：</p>
<div class="wp_codebox">
<pre>[<span style="color: #2b91af">Authorize</span>]
<span style="color: blue">public </span><span style="color: #2b91af">ActionResult </span>Edit(<span style="color: blue">int </span>id) {

    <span style="color: #2b91af">Dinner </span>dinner = dinnerRepository.GetDinner(id);

    <span style="color: blue">if </span>(!dinner.IsHostedBy(User.Identity.Name))
        <span style="color: blue">return </span>View(<span style="color: #a31515">"InvalidOwner"</span>);

    <span style="color: blue">return </span>View(<span style="color: blue">new </span><span style="color: #2b91af">DinnerFormViewModel</span>(dinner));
}</pre>
</div>
<p>然而这种方式存在或多或少的问题，例如：</p>
<ul>
<li>IsBookAuthorized将分散于不同的Action或者BLL层中，对于统一的Authorized管理带来问题。 </li>
<li>实际的Authorized执行已经渗透到Action或者Serivce内部，我们更期待在Action调用之前对此已经进行了处理。 </li>
</ul>
<h2>思考的瞬间</h2>
<p>那么，统一的处理该如何着手实现更优雅的、更统一的Authorize处理呢？显然MVC自带的Authorize特性，为我们提供了可选择的思路：</p>
<div class="wp_codebox">
<pre>[<span style="color: #2b91af">Authorize</span>(Users = <span style="color: #a31515">"Anytao"</span>)]
<span style="color: blue">public </span><span style="color: #2b91af">ActionResult </span>Edit(<span style="color: blue">int </span>id)
{
    <span style="color: blue">return </span>View();
}</pre>
</div>
<p>Authorize标记通过对于Users或者Roles的定义，来对Edit Action的执行进行&ldquo;预&rdquo;Authorize授权，那么登陆用户为Anytao的用户才有权对BookController Edit进行访问，否则将无权访问。显然，这种方式对于满足我们</p>
<ul>
<li>统一Authorize处理 </li>
<li>在Action调用之前进行授权验证 </li>
</ul>
<p>的目标是统一的。所以，我们可以借助这种方式实现自定义的统一Authorize处理方案。</p>
<h2>统一Authorize解决方案</h2>
<p>有了指导方针，我们就可以有的放肆了，我们的方案同样是应用ActionFilter实现对Authorize处理，上次的范例是{<a href="http://anytao.net/blog/post/2009/04/21/anytao-mvc-04-actioninrole.aspx">[一步一步MVC]第四回：使用ActionSelector控制Action的选择</a>}。显然我们可以在OnActionExecuting事件中对Action进行&ldquo;预&rdquo;处理，将关于Authorize的验证过程统一在OnActionExecuting中进行，就可以对标记的Action实现调用之前的过滤了，所以我们首先实现一个AuthorizeAttributeBase，例如：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code03, 2009/04/22                    
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">public abstract class </span><span style="color: #2b91af">AuthorizeAttributeBase </span>: <span style="color: #2b91af">ActionFilterAttribute
</span>{
    <span style="color: blue">public </span>AuthorizeAttributeBase()
    { 
    }

    <span style="color: blue">public </span>AuthorizeAttributeBase(<span style="color: blue">string </span>key)
    {
        Key = key;
    }

    <span style="color: blue">public override void </span>OnActionExecuting(<span style="color: #2b91af">ActionExecutingContext </span>filterContext)
    {</pre>
<pre><span style="color: green">        // Authorize handler </span>
    }

    <span style="color: blue">public string </span>Key { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }

    <span style="color: blue">protected abstract bool </span>IsAuthorized(<span style="color: blue">int </span>id);
}</pre>
</div>
<p>而具体的验证则在具体实现类中，例如我们对Book的验证：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code04, 2009/04/22                    
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">public class </span><span style="color: #2b91af">BookAuthorizeAttribute </span>: <span style="color: #2b91af">AuthorizeAttributeBase
</span>{
    <span style="color: blue">protected override bool </span>IsAuthorized(<span style="color: blue">int </span>id)
    {
        <span style="color: blue">return </span>(<span style="color: blue">new </span><span style="color: #2b91af">IAuthorizeService</span>()).IsBookAuthorized(id);
    }
}</pre>
</div>
<p>对于验证的处理必须解决两方面的问题：</p>
<ul>
<li>在AuthorizeAttributeBase中获取待过滤Action中的参数（Index(<span style="color: blue">int </span>id)），一般而言我们需要对id进行验证，那么传入id的值该如何处理。 </li>
<li>在AuthorizeAttributeBase对于非法用户的处理，一般而言就是导航到NotValid页面。 </li>
</ul>
<h4>在OnActionExecuting中获取Action参数</h4>
<p>我们采用的方法是通过filterContext的ActionParameters来获取参数值，通过参数的Key来获取其值，例如：</p>
<div class="wp_codebox">
<div class="wp_codebox">
<pre><span style="color: blue">if </span>(filterContext.ActionParameters.ContainsKey(key))
{
    value = <span style="color: blue">int</span>.Parse(filterContext.ActionParameters[key].ToString());
}</pre>
</div>
</div>
<h4>在OnActionExecuting中导航到不同的View</h4>
<p>这也是一个简单的处理，我们只要指定好filterContext的Result为指定的ViewResult即可实现我们的目标：</p>
<div class="wp_codebox">
<pre>filterContext.Result = <span style="color: blue">new </span><span style="color: #2b91af">ViewResult</span>{
    ViewName = <span style="color: #a31515">"NotValid"
</span>};</pre>
</div>
<p>解决了上述问题，就基本实现了对Authorize进行统一处理的目标，至于具体的Authorize逻辑，不同的业务可以在不同的业务层进行封装。例如对于Book资源的处理可以统一在IBookService中，对于User资源的处理可以统一在IUserService中（不过显然我们已经有了MVC自带的Authorize，不必重复），对于其他的资源也相应的处理在不同的业务层中。</p>
<p>下面是AuthorizeAttributeBase和BookAuthorizeAttribute的完整代码：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code03, 2009/04/22                    
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">public abstract class </span><span style="color: #2b91af">AuthorizeAttributeBase </span>: <span style="color: #2b91af">ActionFilterAttribute
</span>{
    <span style="color: blue">public </span>AuthorizeAttributeBase()
    { 
    }

    <span style="color: blue">public </span>AuthorizeAttributeBase(<span style="color: blue">string </span>key)
    {
        Key = key;
    }

    <span style="color: blue">public override void </span>OnActionExecuting(<span style="color: #2b91af">ActionExecutingContext </span>filterContext)
    {
        <span style="color: blue">string </span>key = <span style="color: blue">string</span>.IsNullOrEmpty(Key) ? <span style="color: #a31515">"id" </span>: Key;

        <span style="color: blue">int </span>id;

        <span style="color: blue">if </span>(filterContext.ActionParameters.ContainsKey(key))
        {
            <span style="color: blue">if </span>(!<span style="color: blue">int</span>.TryParse(filterContext.ActionParameters[key].ToString(), <span style="color: blue">out </span>id))
            {
                id = 0;
            }
        }
        <span style="color: blue">else
        </span>{
            id = 0;
        }

        <span style="color: blue">if </span>(id &gt; 0)
        {
            <span style="color: blue">if </span>(IsAuthorized(id))
            {
                <span style="color: blue">base</span>.OnActionExecuting(filterContext);
            }
            <span style="color: blue">else
            </span>{
                filterContext.Result = <span style="color: blue">new </span><span style="color: #2b91af">ViewResult</span>{
                    ViewName = <span style="color: #a31515">"NotValid"
                </span>};


            }
        }
        <span style="color: blue">else
        </span>{
            filterContext.Result = <span style="color: blue">new </span><span style="color: #2b91af">ViewResult</span>{
                    ViewName = <span style="color: #a31515">"NotValid"
                </span>};
        }
    }

    <span style="color: blue">public string </span>Key { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }

    <span style="color: blue">protected abstract bool </span>IsAuthorized(<span style="color: blue">int </span>id);
}</pre>
</div>
<p>接下来就是如何应用了。</p>
<h2>在Controller中应用统一Authorize处理</h2>
<p>下面是我们的应用，还是对于<a href="http://anytao.net/Book/index/1">http://anytao.net/Book/index/1</a>的访问，我们可以像下面这样应用：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code05, 2009/04/22                    
// Author  : Anytao, http://www.anytao.com
</span>[<span style="color: #2b91af">BookAuthorize</span>(Key=<span style="color: #a31515">"id"</span>)]
<span style="color: blue">public </span><span style="color: #2b91af">ActionResult </span>Index(<span style="color: blue">int </span>id)
{
    <span style="color: #2b91af">Book </span>model = (<span style="color: blue">new </span><span style="color: #2b91af">IBookService</span>()).GetBook(id);

    <span style="color: blue">return </span>View(model);
}</pre>
</div>
<p>对比前后的两种方案，我想孰优孰劣显而易见。<span style="color: #2b91af">BookAuthorize</span>显然以更优雅的方式实现了对于Authorize这回事儿的处理，也基本达到了原来的目标。我们的验证逻辑没有散落在系统四处，如何同时需要对Book的Index进行多个逻辑的验证，我们的方式也变得很简单，例如：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code05, 2009/04/22                    
// Author  : Anytao, http://www.anytao.com
</span>[<span style="color: #2b91af">BookAuthorize</span>(Key=<span style="color: #a31515">"id"</span>), <span style="color: #2b91af">TaskAuthorize</span>(Key=<span style="color: #a31515">"id"</span>)]
<span style="color: blue">public </span><span style="color: #2b91af">ActionResult </span>Index(<span style="color: blue">int </span>id)
{
    <span style="color: #2b91af">Book </span>model = (<span style="color: blue">new </span><span style="color: #2b91af">IBookService</span>()).GetBook(id);

    <span style="color: blue">return </span>View(model);
}</pre>
</div>
<p>不过，我们需要对id的复用进行一点思考，不过那已经是另外一回儿事儿了。对本文而言，我已经达到了目标。当然，这也许不是最好的方案，所以我<span style="color: #ff0000;">期待您的更好方案</span>，因为技术需要切磋和共享。</p>
<p>又是一个小技巧，希望给你帮助。</p>
<p>&nbsp;</p>
<div class="wp_codebox">
<pre>代码下载[<a href="http://files.cnblogs.com/anytao/anytao_mvc_UnifyAuthorize.rar">anytao_mvc_actionauthorize</a>]，更多关注，尽在<a href="http://anytao.net/blog">anytao.net/blog</a></pre>
</div>
<p>&nbsp; </p>
<div id="MySignature">
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/04/23 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a> | <a href="http://anytao.net/blog/post/2009/04/23/anytao-mvc-05-actionauthorize.aspx" title="http://anytao.net/blog/post/2009/04/23/anytao-mvc-05-actionauthorize.aspx">http://anytao.net/blog/post/2009/04/23/anytao-mvc-05-actionauthorize.aspx</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</p>
</div><img src ="http://www.cnblogs.com/anytao/aggbug/1441706.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47987/" target="_blank">预测：Twitter最可能收购的十家公司</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[一步一步MVC]第一回：使用ActionSelector控制Action的选择</title><link>http://www.cnblogs.com/anytao/archive/2009/04/22/anytao-mvc-01-actioninrole.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Tue, 21 Apr 2009 16:33:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/04/22/anytao-mvc-01-actioninrole.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1440883.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/04/22/anytao-mvc-01-actioninrole.html#Feedback</comments><slash:comments>40</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1440883.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1440883.html</trackback:ping><description><![CDATA[<p><strong><a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a> | <a href="http://anytao.net/">anytao.net</a></span></strong></p>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.04.21&nbsp; 作者：</span><a href="http://about.anytao.com/"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，Anytao原创作品，转贴请注明作者和出处。</span></p>
<p>ActionFilter一定是MVC控制中对于Action控制中最值得研究的玩意，在项目实际中我们不可避免的使用例如：</p>
<ul>
<li>HandleError </li>
<li>Authorized </li>
<li>OutputCache</li>
</ul>
<p>在本文中，我们应用Action Selector方式进行Action的选择，想要阐述清楚这个问题，我们从实际的问题出发来关注。</p>
<h2>实际的问题，从和老赵的对话了解</h2>
<p>我们有个业务室这样的：系统有不同的角色，例如Admin、Client、Agent。假设有个功能叫Book/List，那么就对应了一个List这样的View和action为List这样的BookController，现在，我们的情况是对于不同的角色，所对应的List是不同的。Admin看到的Book/List和Client看到的Book/List是不同的，那么通过Url：<a href="http://anytao.com/Book/List/123">http://anytao.com/Book/List/123</a>，不同的角色如何处理，差不多就这样，是否清楚。</p>
<p><a target="_blank" href="http://about.anytao.com">我</a>：那么对于同一Action如何更好的return到不同的view？</p>
<p><a target="_blank" href="/jeffreyzhao/">老赵</a>：具体问题是什么呢？</p>
<p><a target="_blank" href="http://about.anytao.com">我</a>： 我现在能想到的是在Action中根据角色Return到不同的View，简单的办法就是在List Action根据角色Return到不同的View。问题是，还有什么更好的办法。</p>
<p><a target="_blank" href="/jeffreyzhao/">老赵</a>：准备n各action，分别加上自定的ActionSelector，不要用一个Action，不用一个Action然后在里面if。</p>
<div class="wp_codebox">
<pre>[OnlyInRole(<span style="color: #a31515">"admin"</span>)] 
[<span style="color: #2b91af">ActionName</span>(<span style="color: #a31515">"List"</span>)]
ListForAdmin() 
{
}

[OnlyInRole(<span style="color: #a31515">"user"</span>)] 
[<span style="color: #2b91af">ActionName</span>(<span style="color: #a31515">"List"</span>)]
ListForUser() 
{
}</pre>
</div>
<p>OnlyInRole需要自己写，不过就几行话</p>
<p><a target="_blank" href="http://about.anytao.com">我</a>： 哈哈，差不多了，谢啦。</p>
<p>根据老赵的指导，我对此思路进行了必要的探讨，感受果然不同凡响，很好很暴力。 </p>
<h2>解决方案</h2>
<p>为了实现对于Action进行Selector的具体实现，我选择对<span style="color: #2b91af">ActionNameSelectorAttribute </span>进行扩展，参考ActionName的实现方式，对于按照RoleType进行过滤的需求显然有很好的借鉴价值，以ActionNameAttribute为例，其具体实现为：</p>
<div class="wp_codebox">
<pre>[<span style="color: #2b91af">AttributeUsage</span>(<span style="color: #2b91af">AttributeTargets</span>.Method, AllowMultiple = <span style="color: blue">false</span>, Inherited = <span style="color: blue">true</span>)]
<span style="color: blue">public sealed class </span><span style="color: #2b91af">ActionNameAttribute </span>: <span style="color: #2b91af">ActionNameSelectorAttribute </span>{

    <span style="color: blue">public </span>ActionNameAttribute(<span style="color: blue">string </span>name) {
        <span style="color: blue">if </span>(<span style="color: #2b91af">String</span>.IsNullOrEmpty(name)) {
            <span style="color: blue">throw new </span><span style="color: #2b91af">ArgumentException</span>(<span style="color: #2b91af">MvcResources</span>.Common_NullOrEmpty, <span style="color: #a31515">"name"</span>);
        }

        Name = name;
    }

    <span style="color: blue">public string </span>Name {
        <span style="color: blue">get</span>;
        <span style="color: blue">private set</span>;
    }

    <span style="color: blue">public override bool </span>IsValidName(<span style="color: #2b91af">ControllerContext </span>controllerContext, <span style="color: blue">string </span>actionName, <span style="color: #2b91af">MethodInfo </span>methodInfo) {
        <span style="color: blue">return </span><span style="color: #2b91af">String</span>.Equals(actionName, Name, <span style="color: #2b91af">StringComparison</span>.OrdinalIgnoreCase);
    }

}</pre>
</div>
<p>再来了解ActionNameSelectorAttribute抽象类的定义，其主要提供了对Action进行Select时的IsValidName判断约定，例如ActionNameSelectorAttribute的定义：</p>
<div class="wp_codebox">
<pre>[<span style="color: #2b91af">AttributeUsage</span>(<span style="color: #2b91af">AttributeTargets</span>.Method, AllowMultiple = <span style="color: blue">false</span>, Inherited = <span style="color: blue">true</span>)]
<span style="color: blue">public abstract class </span><span style="color: #2b91af">ActionNameSelectorAttribute </span>: <span style="color: #2b91af">Attribute </span>{
    <span style="color: blue">public abstract bool </span>IsValidName(<span style="color: #2b91af">ControllerContext </span>controllerContext, <span style="color: blue">string </span>actionName, <span style="color: #2b91af">MethodInfo </span>methodInfo);
}</pre>
</div>
<p>所以，对ActionNameSelecterAttribute进行扩展变得异常简单，下面是一个最简单的实现，肯定让我们耳目一新：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code01, 2009/04/17                    
// Author  : Anytao, http://www.anytao.com
</span><span style="color: blue">public class </span><span style="color: #2b91af">ActionInRoleAttribute </span>: <span style="color: #2b91af">ActionNameSelectorAttribute
</span>{
    <span style="color: blue">public </span>ActionInRoleAttribute(<span style="color: #2b91af">RoleType </span>role)
    {
        <span style="color: blue">this</span>.role = role;
    }

    <span style="color: blue">public override bool </span>IsValidName(<span style="color: #2b91af">ControllerContext </span>controllerContext, <span style="color: blue">string </span>actionName, System.Reflection.<span style="color: #2b91af">MethodInfo </span>methodInfo)
    {
        <span style="color: blue">if </span>(controllerContext.HttpContext.User.IsInRole(role.ToString()))
        {
            <span style="color: blue">return true</span>;
        }
        <span style="color: blue">else
        </span>{
            <span style="color: blue">return false</span>;
        }
    }

    <span style="color: blue">private </span><span style="color: #2b91af">RoleType </span>role;
}</pre>
</div>
<p>我们的逻辑其实很简单，借助于<span style="color: #2b91af;">IPrincipal</span>的IsInRole方法，可以很简单的根据role的定义进行IsValidName过滤，例如我们的应该可以就是：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code02, 2009/04/17                    
// Author  : Anytao, http://www.anytao.com
</span>[<span style="color: #2b91af">AcceptVerbs</span>(<span style="color: #2b91af">HttpVerbs</span>.Get)]
[<span style="color: #2b91af">ActionName</span>(<span style="color: #a31515">"List"</span>)]
[<span style="color: #2b91af">ActionInRole</span>(<span style="color: #2b91af">RoleType</span>.Client)]
<span style="color: blue">public </span><span style="color: #2b91af">ActionResult </span>ClientList(<span style="color: blue">int </span>id)
{
    <span style="color: blue">return </span>View(
        <span style="color: #a31515">"ClientBookList"</span>,
        <span style="color: blue">new </span><span style="color: #2b91af">Book
        </span>{
            ID = id,
            Name = <span style="color: blue">string</span>.Empty
        });
}

<span style="color: green">// Release : code03, 2009/04/17                    
// Author  : Anytao, http://www.anytao.com
</span>[<span style="color: #2b91af">AcceptVerbs</span>(<span style="color: #2b91af">HttpVerbs</span>.Get)]
[<span style="color: #2b91af">ActionName</span>(<span style="color: #a31515">"List"</span>)]
[<span style="color: #2b91af">ActionInRole</span>(<span style="color: #2b91af">RoleType</span>.Admin)]
<span style="color: blue">public </span><span style="color: #2b91af">ActionResult </span>AdminList(<span style="color: blue">int </span>id)
{
    <span style="color: blue">return </span>View(
        <span style="color: #a31515">"AdminBookList"</span>,
        <span style="color: blue">new </span><span style="color: #2b91af">Book
        </span>{
            ID = id,
            Name = <span style="color: blue">string</span>.Empty
        });
}</pre>
</div>
<p>调用List Action时，根据登陆用户的角色来决定具体执行的Action（ClientList或者AdminList），并由不同的Action导航到不同的View（ClientBookList或者AdminBookList），而对于不同Action访问的URL都是一样的（<a href="http://anytao.com/Book/List/123">http://anytao.com/Book/List/123</a>），同时避免了在服务层对角色的判断，某种程度上按照RoleType对于Controller层进行了&ldquo;注入&rdquo;，使得Controller层的逻辑不在关心Action过滤的问题。</p>
<p>不过，在应用上还有一些值得注意的问题：</p>
<ul>
<li>使用非泛型ActionLink方法调用应用<span style="color: #2b91af">ActionInRole</span> 的Action </li>
</ul>
<p>一般而言，我们提倡应用强类型ModelData在View层进行操作，那么泛型方法ActionLink值得推荐，</p>
<div class="wp_codebox">
<pre><span style="color: blue">&lt;</span><span style="color: #a31515">p</span><span style="color: blue">&gt;
    </span><span>&lt;%</span><span style="color: blue">= </span>Html.ActionLink&lt;<span style="color: #2b91af">BookController</span>&gt;(c =&gt; c.List(Model.ID), <span style="color: #a31515">"List"</span>) <span>%&gt;
</span><span style="color: blue">&lt;/</span><span style="color: #a31515">p</span><span style="color: blue">&gt;</span></pre>
</div>
<p>然而，应用被ActionInRole标记的，同时被ActionName重命名的Action，将不被识别，我们只好以非泛型方式实现对于一名多用的Action来调用：</p>
<div class="wp_codebox">
<pre><span style="color: blue">&lt;</span><span style="color: #a31515">p</span><span style="color: blue">&gt;
    </span><span>&lt;%</span><span style="color: blue">= </span>Html.ActionLink(<span style="color: #a31515">"List"</span>, <span style="color: #a31515">"List"</span>, <span style="color: blue">new </span>{ id=Model.ID }) <span>%&gt;
</span><span style="color: blue">&lt;/</span><span style="color: #a31515">p</span><span style="color: blue">&gt;</span></pre>
</div>
<ul>
<li>在return View中通过制定ViewName进行返回，来选择适合的View，例如 </li>
</ul>
<div class="wp_codebox">
<pre><span style="color: blue">return </span>View(
    <span style="color: #a31515">"AdminBookList"</span>,
    <span style="color: blue">new </span><span style="color: #2b91af">Book
    </span>{
        ID = id,
        Name = <span style="color: blue">string</span>.Empty
    });</pre>
</div>
<p>因为默认情况下，MVC引擎是以ActionName进行返回的，在我们的应用中必须以这种方式进行。 </p>
<h2>结论</h2>
<p>本文着重于应用，而没有特别对什么是ActionFilter进行探讨，我们在合适的时间再次与MVC握手，对此进行进一步进行讨论。</p>
<p>&nbsp;</p>
<div class="wp_codebox">
<pre>更多关注，尽在<a href="http://anytao.net/blog">anytao.net/blog</a></pre>
</div>
<p>&nbsp;</p>
<p>特别鸣谢：</p>
<ul>
<li><a target="_blank" href="/jeffreyzhao/">老赵</a>，该方案是老赵MSN提议的解决方案，经实际测试果然名不虚传，故做此文以济之。 </li>
</ul>
<div id="MySignature">
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/04/21 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a> | <a href="http://anytao.net/blog/post/2009/04/21/anytao-mvc-04-actioninrole.aspx" title="http://anytao.net/blog/post/2009/04/21/anytao-mvc-04-actioninrole.aspx">http://anytao.net/blog/post/2009/04/21/anytao-mvc-04-actioninrole.aspx</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</p>
</div><img src ="http://www.cnblogs.com/anytao/aggbug/1440883.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47986/" target="_blank">网易澄清:与暴雪合资公司仅提供技术支持</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[开发故事]第三回，实现集合类Sort自定义排序</title><link>http://www.cnblogs.com/anytao/archive/2009/04/12/anytao_devstory_03_customcomparison.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Sun, 12 Apr 2009 13:58:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/04/12/anytao_devstory_03_customcomparison.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1434331.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/04/12/anytao_devstory_03_customcomparison.html#Feedback</comments><slash:comments>22</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1434331.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1434331.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<p><strong><a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a>&nbsp; </span></strong></p>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.04.12 作者：</span><a href="http://about.anytao.com"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，Anytao原创作品，转贴请注明作者和出处。</span></p>
<p>对集合元素进行排序是经常发生的事情，事实上大部分的集合类型都默认实现了Sort方法，进行其元素的排序操作。例如List&lt;T&gt;集合的Sort方法有：</p>
<div class="wp_codebox">
<pre><span style="color: blue">public void </span>Sort();
<span style="color: blue">public void </span>Sort(<span style="color: #2b91af">Comparison</span>&lt;T&gt; comparison);
<span style="color: blue">public void </span>Sort(<span style="color: #2b91af">IComparer</span>&lt;T&gt; comparer);
<span style="color: blue">public void </span>Sort(<span style="color: blue">int </span>index, <span style="color: blue">int </span>count, <span style="color: #2b91af">IComparer</span>&lt;T&gt; comparer);</pre>
</div>
<p>在排序使用上，四个Sort是大同小异，唯一不同的是大部分情况下，排序的要求决定了我们不能完全满足于默认排序的情况，因为Framework根本不清楚&ldquo;你&rdquo;排序的目的，例如：</p>
<div class="wp_codebox">
<pre><span style="color: #2b91af">BookStore </span>bs = <span style="color: blue">new </span><span style="color: #2b91af">BookStore
</span>{
    Books = <span style="color: blue">new </span><span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">Book</span>&gt; { 
        <span style="color: blue">new </span><span style="color: #2b91af">Book</span>{ID = 1, Name=<span style="color: #a31515">"你必须知道的.NET"</span>, Price=69, PublishDate=<span style="color: #2b91af">DateTime</span>.Parse(<span style="color: #a31515">"2008-3-30"</span>)},
        <span style="color: blue">new </span><span style="color: #2b91af">Book</span>{ID = 2, Name=<span style="color: #a31515">"Silverlight完美征程"</span>, Price=75, PublishDate=<span style="color: #2b91af">DateTime</span>.Parse(<span style="color: #a31515">"2009-4-30"</span>)},
        <span style="color: blue">new </span><span style="color: #2b91af">Book</span>{ID =3, Name=<span style="color: #a31515">"博客园精华集"</span>, Price=72, PublishDate=<span style="color: #2b91af">DateTime</span>.Parse(<span style="color: #a31515">"2009-5-3"</span>)}    
    }
};</pre>
</div>
<h2>实现自定义的排序算法</h2>
<p>如果需要对书店的书目进行排序，那么在我们的小示例中至少可以按照书名、书价和出版日期进行排序，因此.NET Framework在设计上为Sort提供了很好的扩展，通常情况下我们需要实现自定义的comparison和comparer，例如：</p>
<div class="wp_codebox">
<pre>            <span style="color: green">// Release : code01, 2009/04/12                    
            // Author  : Anytao, http://www.anytao.com 
            // List    : Protram.cs

            //02 Sort by custom comparison
            </span>bs.Books.Sort((a, b) =&gt; { <span style="color: blue">return </span>a.Price.CompareTo(b.Price); });
<span style="color: green">
            </span><span style="color: blue">foreach </span>(<span style="color: blue">var </span>item <span style="color: blue">in </span>bs.Books)
            {
                <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: blue">string</span>.Format(<span style="color: #a31515">"{0}:{1}, {2}"</span>, item.Name, item.Price, item.PublishDate.ToString()));
            }</pre>
</div>
<p>你看利用Lambda表达式实现一个Custom Comparison是何其简单：</p>
<div class="wp_codebox">
<pre>bs.Books.Sort((a, b) =&gt; { <span style="color: blue">return </span>a.Price.CompareTo(b.Price); });</pre>
</div>
<p>输出的结果为：</p>
<p><a href="/images/cnblogs_com/anytao/162192/o_anytao_devstory_04_01.png"><img height="222" width="489" src="http://images.cnblogs.com/cnblogs_com/anytao/162192/o_anytao_devstory_04_01.png" alt="o_anytao_devstory_04_01[1]" border="0" title="o_anytao_devstory_04_01[1]" style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" /></a> </p>
<p>如果我们实现以出版日期进行排序的Custom Comparison，应该是这样：</p>
<div class="wp_codebox">
<pre>bs.Books.Sort((a, b) =&gt; { <span style="color: blue">return </span>a.PublishDate.CompareTo(b.PublishDate); });</pre>
</div>
<p>排序的结果如我所愿：</p>
<p><a href="/images/cnblogs_com/anytao/162192/o_anytao_devstory_04_02.png"><img height="188" width="489" src="http://images.cnblogs.com/cnblogs_com/anytao/162192/o_anytao_devstory_04_02.png" alt="o_anytao_devstory_04_02[1]" border="0" title="o_anytao_devstory_04_02[1]" style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" /></a></p>
<p>利用Lamdba表达式实现的Comparison变得非常简单，优雅有度，我们回归复杂将Lamdba表达式解析为匿名方法（Anonymous Method）：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code01, 2009/04/12                    
// Author  : Anytao, http://www.anytao.com 
// List    : Protram.cs

//03 Sort by custom comparison: Anonymous Method
</span>bs.Books.Sort(<span style="color: blue">delegate</span>(<span style="color: #2b91af">Book </span>a, <span style="color: #2b91af">Book </span>b)
{
    <span style="color: blue">return </span>a.Price.CompareTo(b.Price);
});</pre>
</div>
<p>如果你对匿名方法还心存芥蒂，那么我们回归Custom Comparison的最本源实现： </p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code01, 2009/04/12                    
// Author  : Anytao, http://www.anytao.com 
// List    : BookComparison.cs

</span><span style="color: blue">public class </span><span style="color: #2b91af">BookComparison </span>: <span style="color: #2b91af">IComparer</span>&lt;<span style="color: #2b91af">Book</span>&gt;
{
    <span style="color: blue">public int </span>Compare(<span style="color: #2b91af">Book </span>x, <span style="color: #2b91af">Book </span>y)
    {
        <span style="color: blue">return </span>x.Price.CompareTo(y.Price);
    }
}</pre>
</div>
<p>利用<span style="color: #2b91af">BookComparison </span>进行比较，</p>
<div class="wp_codebox">
<pre><span style="color: green">//04 Sort by custom comparison: BookComparison
</span>bs.Books.Sort(<span style="color: blue">new </span><span style="color: #2b91af">BookComparison</span>().Compare);</pre>
</div>
<p>输出的结果和bs.Books.Sort((a, b) =&gt; { <span style="color: blue">return </span>a.Price.CompareTo(b.Price); });一样，可谓皆大欢喜。</p>
<p>以自定义方式可以实现的更多的控制，例如我们重构BookComparison：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code01, 2009/04/12                    
// Author  : Anytao, http://www.anytao.com 
// List    : BookComparison.cs

</span><span style="color: blue">public class </span><span style="color: #2b91af">BookComparison </span>: <span style="color: #2b91af">IComparer</span>&lt;<span style="color: #2b91af">Book</span>&gt;
{
    <span style="color: blue">private </span><span style="color: #2b91af">ComparisonType </span>type;

    <span style="color: blue">public </span>BookComparison(<span style="color: #2b91af">ComparisonType </span>type)
    {
        <span style="color: blue">this</span>.type = type;
    }

    <span style="color: blue">public int </span>Compare(<span style="color: #2b91af">Book </span>x, <span style="color: #2b91af">Book </span>y)
    {
        <span style="color: blue">switch </span>(<span style="color: blue">this</span>.type)
        {
            <span style="color: blue">case </span><span style="color: #2b91af">ComparisonType</span>.Price:
                <span style="color: blue">return </span>x.Price.CompareTo(y.Price);
                <span style="color: blue">break</span>;
            <span style="color: blue">case </span><span style="color: #2b91af">ComparisonType</span>.PublishDate:
                <span style="color: blue">return </span>x.PublishDate.CompareTo(y.PublishDate);
                <span style="color: blue">break</span>;
            <span style="color: blue">default</span>:
                <span style="color: blue">break</span>;
        }

        <span style="color: blue">return </span>0;
    }
}</pre>
</div>
<p>添加一个ComparisonType结构，在BookComparson初始化时决定Comparison的方式：</p>
<div class="wp_codebox">
<pre><span style="color: green">//04 Sort by custom comparison: BookComparison
</span>bs.Books.Sort(<span style="color: blue">new </span><span style="color: #2b91af">BookComparison</span>(<span style="color: #2b91af">ComparisonType</span>.PublishDate).Compare);</pre>
</div>
<h2>结论</h2>
<p>自定义Comparison为实现更好的Sort控制，提供了很好的扩展机制。在我们的实际应用中，对于例如BookStore这样的具体应用而言，我更推荐以LINQ的OrderBy来实现，例如：</p>
<div class="wp_codebox">
<pre><span style="color: green">//05 Sort by Linq
</span><span style="color: blue">var </span>list = <span style="color: blue">from </span>c <span style="color: blue">in </span>bs.Books
           <span style="color: blue">orderby </span>c.PublishDate <span style="color: blue">ascending
           select </span>c;

<span style="color: blue">foreach </span>(<span style="color: blue">var </span>item <span style="color: blue">in </span>list)
{
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: blue">string</span>.Format(<span style="color: #a31515">"{0}:{1}, {2}"</span>, item.Name, item.Price, item.PublishDate.ToString()));
}</pre>
</div>
<p>orderby子句可以选择任意的排序条件，同时ascending或者descending控制升序和降序。</p>
<p>何去何从，看官自评。</p>
<p>&nbsp;</p>
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/04/12 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a> | <a href="http://anytao.net/blog/post/2009/04/12/anytao_devstory_04_customcomparisonhtml.aspx" title="http://anytao.net/blog/post/2009/04/12/anytao_devstory_04_customcomparisonhtml.aspx">http://anytao.net/blog/post/2009/04/12/anytao_devstory_04_customcomparisonhtml.aspx</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided &amp;quotAS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</p><img src ="http://www.cnblogs.com/anytao/aggbug/1434331.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47985/" target="_blank">杰克逊悼念仪式或成史上最大规模Web活动</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[玩转Silverlight]第五回：应用篇，在Silverlight中使用Virtual Earth地图服务</title><link>http://www.cnblogs.com/anytao/archive/2009/03/29/anytao_silverlight_05_usevirtualearth.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Sun, 29 Mar 2009 11:34:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/03/29/anytao_silverlight_05_usevirtualearth.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1414997.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/03/29/anytao_silverlight_05_usevirtualearth.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1414997.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1414997.html</trackback:ping><description><![CDATA[<p><strong><a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a>&nbsp; </span></strong></p>
<h2 align="center"><span style="font-family: 微软雅黑; color: #0000ff; font-size: x-large;">[玩转Silverlight]第五回：应用篇，在Silverlight中使用Virutal Earth地图服务</span></h2>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.03.29 作者：</span><a href="http://about.anytao.com"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，Anytao原创作品，转贴请注明作者和出处。</span></p>
<p>畅游地球是个美好的愿望，随着地图服务的日益完善，我们足不出户畅游全球已变得简单异常。事实上，Google Earth和Virutal Earth已经成为Web服务中的必选目标，为自己的网站加入Earth或者Map地图服务是件非常酷的事情，那么在我们的Silverlight应用中使用地图服务是否能够得心应手呢？</p>
<p>答案是肯定的，我们操作Earth服务只需执行简单的服务调用，就可完成坐地日行八万里的壮举了，而这一切是由<a href="http://www.codeplex.com/views">VIEWs</a>组件封装了Javascript脚本来完成的，通过对Virtual Earth Service的调用，在Silverlight中使用托管代码完成简单消费。</p>
<p>下面我们来看看这一过程是如何实现的？</p>
<p><span style="font-size: medium;"><strong>必要的准备</strong></span></p>
<p>必要的准备其实很简单，主要包括：</p>
<ul>
<li>VIEWS.dll，封装了对脚本的处理逻辑类VEMap。 </li>
<li>ScriptInterop.dll，包含VEMap的基类JSObject。 </li>
<li>views.js，调用Virtual Earth服务。 </li>
</ul>
<p>对此，我们无需多做解释，在代码中自会由明白的演示。</p>
<p><strong><span style="font-size: medium;">实现的过程</span></strong></p>
<ul>
<li>创建Silverlight项目和Web项目（例如Anytao.SLight.MapAccess和Anytao.SLight.MapAccess.Web），在Silverlight项目中Add Reference VIEW和ScriptInterop程序集，在Web项目中引入views脚本。 </li>
<li>在Silverlight宿主页面引入views.js脚本和virtualearth服务脚本 </li>
</ul>
<div class="wp_codebox">
<pre><span style="color: blue">&lt;</span><span style="color: #a31515">script </span><span style="color: red">type</span><span style="color: blue">="text/javascript" </span><span style="color: red">src</span><span style="color: blue">="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1"&gt;&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;    
&lt;</span><span style="color: #a31515">script </span><span style="color: red">type</span><span style="color: blue">="text/javascript" </span><span style="color: red">src</span><span style="color: blue">="views.js"&gt;&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;</span></pre>
</div>
<ul>
<li>为Virtual Earth创建容器 </li>
</ul>
<div class="wp_codebox">
<pre><span style="color: blue">&lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="myMap" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">position</span>:<span style="color: blue">absolute</span>; <span style="color: red">width</span>:<span style="color: blue">640px</span>; <span style="color: red">height</span>:<span style="color: blue">480px</span>; <span style="color: red">top</span>:<span style="color: blue">105px</span>;<span style="color: blue">"&gt;&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;</span></pre>
</div>
<ul>
<li>在Silverlight中添加调用布局 </li>
</ul>
<div class="wp_codebox">
<pre><span style="color: blue">&lt;</span><span style="color: #a31515">Grid </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">="LayoutRoot" </span><span style="color: red">Background</span><span style="color: blue">="Azure"&gt;
    &lt;</span><span style="color: #a31515">StackPanel </span><span style="color: red">Orientation</span><span style="color: blue">="Vertical" &gt;
        &lt;</span><span style="color: #a31515">StackPanel </span><span style="color: red">Orientation</span><span style="color: blue">="Horizontal" </span><span style="color: red">HorizontalAlignment</span><span style="color: blue">="Center" </span><span style="color: red">VerticalAlignment</span><span style="color: blue">="Top"&gt;
            &lt;</span><span style="color: #a31515">TextBox </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">="tbPlace" </span><span style="color: red">Width</span><span style="color: blue">="200" </span><span style="color: red">Height</span><span style="color: blue">="30" </span><span style="color: red">Text</span><span style="color: blue">="Beijing" </span><span style="color: red">Margin</span><span style="color: blue">="5" /&gt;
            &lt;</span><span style="color: #a31515">Button </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">="btnFind" </span><span style="color: red">Width</span><span style="color: blue">="100" </span><span style="color: red">Content</span><span style="color: blue">="Find" </span><span style="color: red">Height</span><span style="color: blue">="30" </span><span style="color: red">Click</span><span style="color: blue">="btnFind_Click" /&gt;
        &lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt; 
        &lt;</span><span style="color: #a31515">HyperlinkButton </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">="codeload" </span><span style="color: red">HorizontalAlignment</span><span style="color: blue">="Center" </span><span style="color: red">Content</span><span style="color: blue">="Code Download" </span><span style="color: red">Margin</span><span style="color: blue">="10" </span><span style="color: red">Click</span><span style="color: blue">="codeload_Click" /&gt;
        &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">HorizontalAlignment</span><span style="color: blue">="Center" </span><span style="color: red">Text</span><span style="color: blue">="2009, Anytao.com" /&gt;
    &lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;</span></pre>
</div>
<ul>
<li>实现具体的调用逻辑 </li>
</ul>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code01, 2009/03/03                    
// Author  : Anytao, http://www.anytao.com 
// List    : Page.xaml.cs
</span><span style="color: blue">public partial class </span><span style="color: #2b91af">Page </span>: <span style="color: #2b91af">UserControl
</span>{
    <span style="color: blue">private </span><span style="color: #2b91af">VEMap </span>map;
    <span style="color: blue">private </span><span style="color: #2b91af">VEShapeLayer </span>layer;

    <span style="color: blue">public </span>Page()
    {
        InitializeComponent();

        Loaded += <span style="color: blue">new </span><span style="color: #2b91af">RoutedEventHandler</span>(Page_Loaded);
        codeload.Content = <span style="color: #a31515">"Download: " </span>+ <span style="color: #2b91af">App</span>.Current.GetType().Namespace;
    }

    <span style="color: blue">void </span>Page_Loaded(<span style="color: blue">object </span>sender, <span style="color: #2b91af">RoutedEventArgs </span>e)
    {
        <span style="color: green">//Create from container
        </span>map = <span style="color: blue">new </span><span style="color: #2b91af">VEMap</span>(<span style="color: #a31515">"myMap"</span>);
        <span style="color: #2b91af">HtmlPage</span>.RegisterScriptableObject(<span style="color: #a31515">"SLMAP"</span>, map);

        <span style="color: green">//Location in Beijing
        </span><span style="color: #2b91af">VELatLong </span>point = <span style="color: blue">new </span><span style="color: #2b91af">VELatLong</span>(39.92, 116.46);
        <span style="color: green">//Loading the earth
        </span>map.LoadMap(point, 11);
    }

    <span style="color: blue">private void </span>btnFind_Click(<span style="color: blue">object </span>sender, <span style="color: #2b91af">RoutedEventArgs </span>e)
    {
        <span style="color: green">//Find a location
        </span>map.Find(<span style="color: blue">string</span>.Empty, tbPlace.Text);
    }
}</pre>
</div>
<ul>
<li>OK，大功告成，我们欣赏并搜索自己的地方了，默认情况下我们首先会看得伟大首都的缩影。 </li>
</ul>
<p>当然，还有更多的控制，我们没有演示，大家可以了解了解VEMap提供的服务和接口，相信你能获取更多超酷的地图探索体验。</p>
<p><strong><span style="font-size: medium;">示例演示</span></strong></p>
<p><iframe scrolling="no" marginwidth="0" frameborder="0" src="http://anytao.net/dev/MapAccess/index.html" marginheight="0" style="width: 640px; height: 680px;"></iframe></p>
<p>&nbsp;</p>
<p><span style="font-size: medium;"><strong>参考文献</strong></span></p>
<ul>
<li><a href="http://www.codeplex.com/views" title="http://www.codeplex.com/views">http://www.codeplex.com/views</a> </li>
</ul>
<p><strong><span style="font-size: medium;">温故知新</span></strong></p>
<ul>
<li><a target="_blank" href="/anytao/archive/2009/01/20/anytao_silverlight_01_communication_handler.html">第一回：基础篇，品尝与HttpHandler通信</a> </li>
<li><a href="/anytao/archive/2009/02/06/anytao_silverlight_02_localization.html">第二回：应用篇，Silverlight本地化</a> </li>
<li><a href="/anytao/archive/2009/02/19/anytao_silverlight_03_rest_part1.html">第三回：基础篇，在Silverlight中使用基于WCF的REST服务（上）</a> </li>
<li><a href="/anytao/archive/2009/02/20/anytao_silverlight_04_rest_part2.html">第四回：基础篇，在Silverlight中使用基于WCF的REST服务（下）</a> </li>
</ul>
<div id="MySignature">
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/03/29 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a> | <a href="http://anytao.net/blog/post/2009/03/18/anytao_silverlight_05_usevirtualearth.aspx" title="http://anytao.net/blog/post/2009/03/18/anytao_silverlight_05_usevirtualearth.aspx">http://anytao.net/blog/post/2009/03/18/anytao_silverlight_05_usevirtualearth.aspx</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided &amp;quotAS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。 </p>
</div><img src ="http://www.cnblogs.com/anytao/aggbug/1414997.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47984/" target="_blank">《商业周刊》:Mozilla的志愿者开发模式被复制</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[你Q我A]你必须知道的.NET，问答时刻</title><link>http://www.cnblogs.com/anytao/archive/2009/03/25/anytao_qa_insidenet.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Wed, 25 Mar 2009 02:45:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/03/25/anytao_qa_insidenet.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1421152.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/03/25/anytao_qa_insidenet.html#Feedback</comments><slash:comments>30</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1421152.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1421152.html</trackback:ping><description><![CDATA[摘要: 问题的解答，常常是留给自己思考的，有时候一个猛然浮现的问题将我拉入混沌，但是思考和探索之后也会豁然开朗；有时候，给他人方便就是给自己方便，但是没有记录的方便不足以给更多人方便；过去的很多时间，我回答了很多问题，但是发现重复回答的比例在直线上升，所以在一个统一的地方，提供统一的管理是最好的方式。那么，从今开始这个方寸土地，就是我记录问答时刻的一亩三分地，任何我熟悉和了解的问题，都将尽己所能为你解忧，同时任何我不知道或闻所未闻的内容，也请您见谅我的无知，但是至少你会得到一个“对不起，我不知道”的答案。&nbsp;&nbsp;<a href='http://www.cnblogs.com/anytao/archive/2009/03/25/anytao_qa_insidenet.html'>阅读全文</a><img src ="http://www.cnblogs.com/anytao/aggbug/1421152.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47977/" target="_blank">Mono 的Virtual PC 虚拟机</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[你必须知道的.NET]第二十八回：说说Name这回事儿</title><link>http://www.cnblogs.com/anytao/archive/2009/03/18/must_net_28.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Tue, 17 Mar 2009 16:06:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/03/18/must_net_28.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1414965.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/03/18/must_net_28.html#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1414965.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1414965.html</trackback:ping><description><![CDATA[<p><strong><a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a>&nbsp; </span></strong></p>
<h2 align="center"><span style="font-family: 微软雅黑; color: #0000ff; font-size: x-large;">[你必须知道的.NET]第二十八回：说说Name这回事儿</span></h2>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.3.18 作者：</span><a href="http://about.anytao.com/"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，原创作品，转贴请注明作者和出处。</span></p>
<p><span style="font-size: medium;">1 缘起</span></p>
<p>老赵在<a href="/JeffreyZhao/archive/2009/03/17/expression-cache-2-simple-key-cache.html">谈表达式树的缓存（2）：由表达式树生成字符串</a>中提到，在描述Type信息时讨论FullName或者AssemblyQualifiedName提供完整的Type信息，虽是小话题，但却是值得有聊的话题。在.NET中反应一个Type名称信息的有以下三个属性，分别是：</p>
<ul>
<li>Name，获取当前成员的名称。 </li>
<li>FullName，获取Type 的完全限定名，包括Type的命名空间，但不包括程序集。 </li>
<li>AssemblyQualifiedName，获取Type的程序集限定名，其中包括从中加载Type 的程序集的名称。事实上，AssemblyQualifiedName被定义为只读abstract属性，具体的实现由其派生类来实现，例如TypeBuilder，我们可以根据其具体实现类型对此有个大致的了解。 </li>
</ul>
<p>此处的定义毋庸置疑是官方的（MSDN），俗话说，事实是检验真理的唯一标准，那么这三个相近的概念，究竟代表了怎样的不同，我们回到事实近看分晓。</p>
<p><span style="font-size: medium;">2 畅聊Name</span></p>
<p><strong>2.1 由简单的开始</strong></p>
<p>由简单开始，我们不妨看看object的三个不同Name返回的事实真相：</p>
<div class="wp_codebox">
<pre><span style="color: blue">static void </span>Main(<span style="color: blue">string</span>[] args)
{
    <span style="color: #2b91af">Type </span>t1 = <span style="color: blue">typeof</span>(<span style="color: blue">object</span>);
    <span style="color: #2b91af">Console</span>.WriteLine(t1.Name);
    <span style="color: #2b91af">Console</span>.WriteLine(t1.FullName);
    <span style="color: #2b91af">Console</span>.WriteLine(t1.AssemblyQualifiedName);
}</pre>
</div>
<p>执行结果呢？</p>
<p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_insidenet_28_01.jpg" /> </p>
<p>诚如MSDN所说，Name返回了简单的类型名称，FullName包含命名空间，而AssemblyQualifiedName则包含程序集全名称。而对于非强名称程序集，其AssemblyQualifiedName依然返回，相关的程序集信息，例如：</p>
<div class="wp_codebox">
<pre><span style="color: #2b91af">Console</span>.WriteLine(t3.AssemblyQualifiedName);</pre>
</div>
<p>Anytao.Learning.ExpressionTree.One, Anytao.Learning.ExpressionTree, Version=1.0. <br />0.0, Culture=neutral, PublicKeyToken=null</p>
<p><strong>2.2 向复杂过度</strong></p>
<p>如果我们只把目光停留在简单类型，那么这三个家伙也不值得花点小时间来注意了，除了简单，还得复杂。所以，我饶尤其是的把Expression拿来抓丁了：</p>
<div class="wp_codebox">
<pre><span style="color: blue">static void </span>Main(<span style="color: blue">string</span>[] args)
{
    <span style="color: #2b91af">Type </span>t2 = <span style="color: blue">typeof</span>(<span style="color: #2b91af">Expression</span>&lt;<span style="color: #2b91af">Func</span>&lt;<span style="color: blue">int</span>, <span style="color: blue">int</span>&gt;&gt;);
    <span style="color: #2b91af">Console</span>.WriteLine(t2.Name);
    <span style="color: #2b91af">Console</span>.WriteLine(t2.FullName);
    <span style="color: #2b91af">Console</span>.WriteLine(t2.AssemblyQualifiedName);
}</pre>
</div>
<p>执行的结果呢？</p>
<p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_insidenet_28_02.jpg" /> </p>
<p>显然，对于答案，引起我们关注的是在Expression&lt;Func&lt;int, int&gt;&gt;中，其FullName的Func&lt;int, int&gt;类型，以及int类型均获取到其AssemblyQualifiedName，而不是FulName。这留给我们一个大大的疑问，对其原因进行一点点深究，我们就可以有这样的思考，Func&lt;T&gt;以及int分别存在于System.Core和mscorlib程序集，对于我们本身程序集而言，完全有可能在其他引用程序集中引入一个FullName相同的Assembly，所以为唯一限定起见，以AssemblyQualifiedName标示Func&lt;T&gt;和int是完全正确的。</p>
<p>同意的问题，存在于List&lt;T&gt;等其他类型。任何可替换类型参数的实际类型，都可能由不同程序集的加载而变得不够&ldquo;唯一&rdquo;，所以AssemblyQualifiedName来限定List&lt;T&gt;的FullName是明智的。</p>
<p><strong>2.3 顺便看看Type.ToString()</strong></p>
<p>Type类型还有一个ToString()，用于返回Type的Name，那么这个Name究竟是这三个中的哪一个呢？如果看了答案，你肯定又一次崩溃：</p>
<div class="wp_codebox">
<pre><span style="color: blue">static void </span>Main(<span style="color: blue">string</span>[] args)
{
    <span style="color: #2b91af">Type </span>t1 = <span style="color: blue">typeof</span>(<span style="color: blue">object</span>);
    <span style="color: #2b91af">Type </span>t2 = <span style="color: blue">typeof</span>(<span style="color: #2b91af">Expression</span>&lt;<span style="color: #2b91af">Func</span>&lt;<span style="color: blue">int</span>, <span style="color: blue">int</span>&gt;&gt;);
    <span style="color: #2b91af">Type </span>t3 = <span style="color: blue">typeof</span>(<span style="color: #2b91af">One</span>);
    <span style="color: #2b91af">Type </span>t4 = <span style="color: blue">typeof</span>(<span style="color: #2b91af">List</span>&lt;<span style="color: blue">int</span>&gt;);
    <span style="color: #2b91af">Console</span>.WriteLine(t1.ToString());
    <span style="color: #2b91af">Console</span>.WriteLine(t2.ToString());
    <span style="color: #2b91af">Console</span>.WriteLine(t3.ToString());
    <span style="color: #2b91af">Console</span>.WriteLine(t4.ToString());
}</pre>
</div>
<pre>我们看看此时的结果：</pre>
<p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_insidenet_28_03.jpg" /> </p>
<p>虽然很无语，Type.ToString()事实上并未返回Name、FullName或者AssemblyQualifiedName，而是不完全的FullName，具体就不做过多陈述了，我们可以由结果看得很明白。</p>
<p><span style="font-size: medium;">3 回到问题</span></p>
<p>显然，FullName在一个程序集中是唯一限定的，包含了所在的命名空间，而AssemblyQualifiedName则更包含其程序集名称，对于复杂类型的例如List&lt;T&gt;这样的类型，即便是FullName也将以AssemblyQualifiedName显示其类型参数，所以对于老赵的方案FullName是完全可以胜任为不同Type实现唯一key值的需求。</p>
<p>你认为呢？</p>
<div id="MySignature">
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/03/18 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a> | <a href="http://anytao.net/blog/post/2009/03/17/must_net_28.aspx" title="http://anytao.net/blog/post/2009/03/17/must_net_28.aspx">http://anytao.net/blog/post/2009/03/17/must_net_28.aspx</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。 </p>
</div>
<p><span style="color: #800000; font-size: medium;">温故知新</span></p>
<p>[<a href="/anytao/archive/2007/04/06/must_net_00.html">开篇有益</a>] <br />[<a href="/anytao/archive/2007/04/07/must_net_01.html">第一回：恩怨情仇：is和as</a>] <br />[<a href="/anytao/archive/2007/04/12/must_net_02.html">第二回：对抽象编程：接口和抽象类</a>] <br />[<a href="/anytao/archive/2007/04/19/must_net_03.html">第三回：历史纠葛：特性和属性</a>] <br />[<a href="/anytao/archive/2007/04/24/must_net_04.html">第四回：后来居上：class和struct</a>] <br />[<a href="/anytao/archive/2007/04/28/must_net_05.html">第五回：深入浅出关键字---把new说透</a>] <br />[<a href="/anytao/archive/2007/05/04/must_net_06.html">第六回：深入浅出关键字---base和this</a>] <br />[<a href="/anytao/archive/2007/05/11/must_net_07.html">第七回：品味类型---从通用类型系统开始</a>] <br />[<a href="/anytao/archive/2007/05/23/must_net_08.html">第八回：品味类型---值类型与引用类型（上）－内存有理</a>] <br />[<a href="/anytao/archive/2007/05/28/must_net_09.html">第九回：品味类型---值类型与引用类型（中）－规则无边</a>] <br />[<a href="/anytao/archive/2007/06/18/must_net_10.html">第十回：品味类型---值类型与引用类型（下）－应用征途</a>] <br />[<a href="/anytao/archive/2007/07/06/must_net_11.html">第十一回：参数之惑---传递的艺术（上）</a>] <br />[<a href="/anytao/archive/2007/07/06/must_net_12.html">第十二回：参数之惑---传递的艺术（下）</a>] <br />[<a href="/anytao/archive/2007/07/22/must_net_13.html">第十三回：从Hello, world开始认识IL</a>] <br />[<a href="/anytao/archive/2007/08/22/must_net_14.html">第十四回：认识IL代码---从开始到现在</a>] <br />[<a href="/anytao/archive/2007/09/10/must_net_15.html">第十五回：继承本质论</a>] <br />[<a href="/anytao/archive/2007/10/01/must_net_16.html">第十六回：深入浅出关键字---using全接触</a>] <br />[<a href="/anytao/archive/2007/11/07/must_net_17.html">第十七回：貌合神离：覆写和重载</a>] <br />[<a href="/anytao/archive/2007/12/03/must_net_18.html">第十八回：对象创建始末（上）</a>] <br />[<a target="_blank" href="/anytao/archive/2007/12/07/must_net_19.html">第十九回：对象创建始末（下）</a>] <br />[<a href="/anytao/archive/2008/05/28/must_net_20.html">第二十回：学习方法论</a>] <br />[<a href="/anytao/archive/2008/07/31/must_net_21.html">第二十一回：认识全面的null</a>] <br />[<a href="/anytao/archive/2008/08/27/must_net_22.html">第二十二回：字符串驻留（上）---带着问题思考</a>] <br />[<a href="/anytao/archive/2008/11/02/must_net_23.html">第二十三回：品味细节，深入.NET的类型构造器</a>] <br />[<a href="/anytao/archive/2009/02/24/must_net_24.html">第二十四回：认识元数据和IL（上）</a>] <br />[<a href="/anytao/archive/2009/02/25/must_net_25.html">第二十五回：认识元数据和IL（中）</a>] <br />[<a href="/anytao/archive/2009/03/05/must_net_27.html">第二十七回：interface到底继承于object吗？</a>]</p><img src ="http://www.cnblogs.com/anytao/aggbug/1414965.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47970/" target="_blank">19岁天才黑客发布首个iPhone 3GS破解软件</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[你必须知道的.NET]第二十七回：interface到底继承于object吗？</title><link>http://www.cnblogs.com/anytao/archive/2009/03/05/must_net_27.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Wed, 04 Mar 2009 18:08:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2009/03/05/must_net_27.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1403550.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2009/03/05/must_net_27.html#Feedback</comments><slash:comments>78</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1403550.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1403550.html</trackback:ping><description><![CDATA[<p><strong><a href="http://book.anytao.com/"><strong><span style="color: #ff0000;">《你必须知道的.NET》网站</span></strong></a></strong> | <strong><span style="color: #0000ff;"><a href="http://www.anytao.com/">Anytao技术博客</a>&nbsp; </span></strong></p>
<h2 align="center"><span style="font-family: 微软雅黑; color: #0000ff; font-size: x-large;">[<span style="font-family: 微软雅黑; color: #0000ff; font-size: x-large;">你必须知道的.NET]第二十七回：interface到底继承于object吗？</span></span></h2>
<p align="right"><span style="font-family: 微软雅黑;">发布日期：2009.03.05 作者：</span><a href="http://about.anytao.com"><span style="font-family: 微软雅黑;">Anytao</span></a> <br /><span style="font-family: 微软雅黑; color: #ff0000;">&copy; 2009 </span><a href="http://www.anytao.com/"><span style="font-family: 微软雅黑; color: #ff0000;">Anytao.com</span></a><span style="font-family: 微软雅黑; color: #ff0000;"> ，Anytao原创作品，转贴请注明作者和出处。</span></p>
<div>
<table border="0" style="border-collapse: collapse">
<colgroup><col style="width: 590px;"></col><col></col><col></col><col></col><col></col><col></col><col></col><col></col><col></col><col></col><col></col><col></col><col></col><col></col><col></col><col></col></colgroup>
<tbody valign="top">
<tr style="background: #87bfd1">
<td style="border-bottom: #9bbb59 1pt solid; border-left: #9bbb59 1pt solid; padding-left: 7px; padding-right: 7px; border-top: #9bbb59 1pt solid; border-right: #9bbb59 1pt solid"><span style="color: white"><img art="Anytao.com" src="http://www.cnblogs.com/images/cnblogs_com/anytao/125111/o_icon_your_info.gif" />说在，开篇之前</span></td>
</tr>
<tr>
<td style="border-bottom: #9bbb59 1pt solid; border-left: #9bbb59 1pt solid; padding-left: 7px; padding-right: 7px; border-top: medium none; border-right: #9bbb59 1pt solid">在.NET世界里，我们常常听到的一句话莫过于&ldquo;System.Object是一切类型的根，是所有类型的父类&rdquo;，以至于我在《你必须知道的.NET》8.1节 以&ldquo;万物归宗：System.Object&rdquo;这样的title为System.Object授予至高荣誉。所以，基于这样的观点就有了下面这句&ldquo;接口是否也继承于System.Object？&rdquo;，事实上这正是今天在技术群里小小讨论的一个插曲。&nbsp; <br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.anytao.com"><span style="color: #ff0000;">www.anytao.com</span></a></td>
</tr>
</tbody>
</table>
</div>
<div>&nbsp;</div>
<p>&nbsp;</p>
<p><b></b></p>
<p><span style="color: #800000; font-size: large;">1 缘起</span></p>
<p>在.NET世界里，我们常常听到的一句话莫过于&ldquo;System.Object是一切类型的根，是所有类型的父类&rdquo;，以至于我在《你必须知道的.NET》8.1节 以&ldquo;万物归宗：System.Object&rdquo;这样的title为System.Object授予至高荣誉。所以，基于这样的观点就有了下面这句&ldquo;接口是否也继承于System.Object？&rdquo;，事实上这正是今天在技术群里小小讨论的一个插曲。</p>
<p>持&ldquo;interface也继承于object&rdquo;，是基于以下的两个观点推断的：</p>
<p><strong>观点一：</strong></p>
<p>接口本质上也是一个class，因为接口类型编译之后在IL中被标识为.class，既然是类那么不可避免的最终继承于System.Object。</p>
<p><strong>观点二：</strong></p>
<p>假如有如下的接口和实现接口的类型：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code01, 2009/03/04                    
// Author  : Anytao, http://www.anytao.com
// List    : IObjectable.cs
</span><span style="color: blue">public interface </span><span style="color: #2b91af">IObjectable
</span>{
}</pre>
</div>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code02, 2009/03/04                    
// Author  : Anytao, http://www.anytao.com
// List    : MyObject.cs
</span><span style="color: blue">public class </span><span style="color: #2b91af">MyObject </span>: <span style="color: #2b91af">IObjectable
</span>{
}</pre>
</div>
<pre>那么，对于IObjectable对象而言，下面的调用是可行的：</pre>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code03, 2009/03/04                    
// Author  : Anytao, http://www.anytao.com
// List    : Program.cs
</span><span style="color: blue">class </span><span style="color: #2b91af">Program
</span>{
    <span style="color: blue">static void </span>Main(<span style="color: blue">string</span>[] args)
    {
        <span style="color: #2b91af">IObjectable </span>obj = <span style="color: blue">new </span><span style="color: #2b91af">MyObject</span>();

        <span style="color: green">//Call Object instance methods
        </span>obj.ToString();
        <span style="color: green">//Call Object static methods
        </span><span style="color: #2b91af">IObjectable</span>.Equals(<span style="color: blue">null</span>, <span style="color: blue">null</span>);
    }
}</pre>
</div>
<p>显然，IObjectable类型变量obj可以访问存在于System.Object中的实例方法ToString()和虚方法Equals，当然其他的几个公共服务也不例外：GetType()、Equals()、GetHashcode()、ReferenceEquals()，也可以由此推断interface可访问Object方法的蛛丝马迹。</p>
<p>不可否认，以上观点的部分推理是完全正确的，但是却遗憾的导致了错误的答案，所以在本文中我将明确的找出：interface不继承于object的原因和原理。关于接口本质话题的深度讨论，请参考《<a href="http://book.anytao.com">你必须知道的.NET</a>》1.5 &ldquo;玩转接口&rdquo;和7.4 &ldquo;面向抽象编程：接口和抽象类&rdquo;的详细分析。</p>
<p><span style="color: #800000; font-size: large;">2 从面向对象寻找答案</span> </p>
<p>为了找出接口继承的原因，我想从接口存在的意义入手是最能够说明问题的办法？接口，就像面向对象设计中的精灵，为OO思想注入了灵魂和活力，接口突破了继承在纵向上的扩展方向，在横向给予对象以更灵活的支持机制。 </p>
<p>接口，封装了对于行为的抽象，定义了实现者必须遵守的契约。例如，实现了<a href="http://msdn2.microsoft.com/hdf3zaf2.aspx" title="ICloneable Interface">System.ICloneable</a>接口的类型被赋予了&ldquo;可以被拷贝&rdquo;这样的契约，实现了<a href="http://msdn2.microsoft.com/h1x9x1b1.aspx" title="IEnumerable Interface">System.Collections.IEnumerable</a>接口的类型被赋予了&ldquo;可以被枚举&rdquo;这样的契约，不同的接口定义了不同的契约，就像不同的法律约束了不同的行为。那么接口应该赋予的契约至少在层次上保持相对的单纯和统一，如果为所有接口都无一例外的赋予GetType()、Equals()、GetHashcode()、ReferenceEquals()还有ToString()这样的契约，未免使得接口的纯洁和统一变得无从谈起，例如强迫任何实现了<a href="http://msdn2.microsoft.com/hdf3zaf2.aspx" title="ICloneable Interface">System.ICloneable</a>接口的类型同时遵守其他的约定是对ICloneable本身的侮辱。 </p>
<p>从接口单一原则延伸思考，一个包含杂七杂八的接口定义显然不是interface应该具有的纯正血统，对于深谙面向对象为何物的.NET设计者而言，这是不言而喻的问题。所以，我们从接口本身的职责和意义出发，决定interface不从System.Object继承是完全正确的。 </p>
<p><span style="color: #800000; font-size: large;">3 在IL探求究竟</span> </p>
<p>再次应用强大的IL武器来探求事实的真相，我们以Reflector打开所有的.NET既有接口，例如IList、IEmumerable、ICollection，都会有个共同的发现那就是你找不到extends <a href="http://msdn2.microsoft.com/e5kfa45b.aspx" title="Object Class">System.Object</a>这样的标识： </p>
<div class="wp_codebox">
<pre>.<span style="color: blue">class public interface abstract </span>auto ansi ICloneable
{
    .custom instance <span style="color: blue">void </span>System.Runtime.InteropServices.ComVisibleAttribute::.ctor(<span style="color: blue">bool</span>) = { <span style="color: blue">bool</span>(<span style="color: blue">true</span>) }
    .method <span style="color: blue">public </span>hidebysig newslot <span style="color: blue">abstract virtual </span>instance <span style="color: blue">object </span>Clone() cil managed
    {
    }
}</pre>
</div>
<pre>自定义类型也是如此，我们看看IObjectable的IL反编译定义：</pre>
<div class="wp_codebox">
<pre>.<span style="color: blue">class public interface abstract </span>auto ansi IObjectable
{
}</pre>
</div>
<pre>而以extends标识继承关系是IL代码告诉我们真相的最佳证明。</pre>
<p><strong>System.Object真是&ldquo;万物归宗&rdquo;吗？</strong> </p>
<p>让我们再次回眸一笑，把Object进行一番把玩，难道一切类型都得继承自Object吗？其实不然。以ILASM.exe进行IL代码编译时，有一个参数选项NOAUTOINHERIT，正如其解释所描述的那样： </p>
<div class="wp_codebox">
<pre>/NOAUTOINHERIT  Disable inheriting from System.Object by <span style="color: blue"><span style="color: #000000;">default</span></span></pre>
</div>
<p>显然NoAutoInherit选项提供了为.NET类型&ldquo;去掉帽子&rdquo;的作用，简单言之就是，在未指定基类时，禁止类型自动从Object继承。 </p>
<p>我们可以玩儿一个翻来覆去的IL游戏，将我们本文开始的Anytao.Insidenet.InterfaceInside.exe控制台程序以ILDASM.exe工具Dump为IL代码My.il，例如MyObject被反编译为： </p>
<div class="wp_codebox">
<pre>.class public auto ansi beforefieldinit Anytao.Insidenet.InterfaceInside.MyObject
       extends [mscorlib]System.Object
       implements Anytao.Insidenet.InterfaceInside.IObjectable
{
  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method MyObject::.ctor

} // end of class Anytao.Insidenet.InterfaceInside.MyObject</pre>
</div>
<p>我们可以选择删除其中所有extends继承的代码，再以ILASM.exe对其进行noautoinherit编译，并生成</p>
<div class="wp_codebox">
<pre>ilasm /exe /output:noobject.exe /noautoinherit my.il</pre>
</div>
<p>新生成的noobject.exe程序将没有从object继承，某种程度上打破了&ldquo;万物归宗&rdquo;的创奇，MyObject就像一个无根之木，飘摇在我机器的某个深处。</p>
<p><span style="color: #800000; font-size: large;">4 结论</span></p>
<p>interface不从object继承，那么足下高见呢？文章虽短，取一瓢饮之，畅也。</p>
<p>那么，我们该如何回答本文开始对此质疑的两种观点呢？</p>
<p><strong>回答观点一：</strong></p>
<p>接口本质上还是一个类，但是一个特殊的类，它的特殊性表现在诸多的方面，例如所有的方法和属性都是抽象的、支持多继承等等，既然特殊那就特殊到底，不继承于任何的父类也是其中之一吧。</p>
<p>虽然这种解释未免牵强，但是如前文所述回到接口本源的角度而言，却是最好的解释。</p>
<p><strong>回答观点二：</strong></p>
<p>.NET一切类型都隐式继承于System.Object，那么对于实现了任何接口的类型而言，例如：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code02, 2009/03/04                    
// Author  : Anytao, http://www.anytao.com
// List    : MyObject.cs
</span><span style="color: blue">public class </span><span style="color: #2b91af">MyObject </span>: <span style="color: #2b91af">IObjectable
</span>{
}</pre>
</div>
<p>其在本质上相当于：</p>
<div class="wp_codebox">
<pre><span style="color: green">// Release : code02, 2009/03/04                    
// Author  : Anytao, http://www.anytao.com
// List    : MyObject.cs
</span><span style="color: blue">public class </span><span style="color: #2b91af">MyObject </span>: <span style="color: #2b91af">Object</span>, <span style="color: #2b91af">IObjectable
</span>{
}</pre>
</div>
<p>所以对于MyObject实例obj而言，obj.ToString()实质是MyObject类继承于object，而不代表接口IObjectable也继承于object。那么<span style="color: #2b91af">IObjectable</span>.Equals()则是编译器做了手脚，将<span style="color: #2b91af">IObjectable</span>.Equals()翻译为<span style="color: #2b91af">Object</span>.Equals()所致（来自<a href="http://ninputer.cnblogs.com/">脑袋</a>高论，表示热烈感谢）。事实上，对于接口声明类型的方法调用，在实现机制上完全不同于一般的直接方法调用和虚方法分派机制，我们将在后续篇幅中详细讨论这一更重要的话题。</p>
<p>好了，interface，想说爱你不容易，可能我们还会再次相遇，也敬请朋友们继续关注：<a href="http://book.anytao.com/">你必须知道的.NET</a>。</p>
<p>友情支持：<a href="http://ninputer.cnblogs.com/">脑袋</a>、<a href="/xinyuperfect">飞林沙</a> 、<a href="/bjclub/">博客园北京俱乐部</a></p>
<hr />
<div id="MySignature">
<p class="class"><a href="http://i.anytao.com/">anytao</a> | <a href="http://www.anytao.com/" class="copyright">&copy; 2009 Anytao.com</a></p>
<p class="class">2009/03/05 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a> | <a href="/anytao/archive/2009/03/05/must_net_27.html" title="http://www.cnblogs.com/anytao/archive/2009/03/04/must_net_26.html">http://www.cnblogs.com/anytao/archive/2009/03/05/must_net_27.html</a></p>
<p class="class">本文以&ldquo;现状&rdquo;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.</p>
<p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。 </p>
<p><span style="color: #800000; font-size: medium;">参考文献</span></p>
</div>
<ul>
<li>《<a href="http://book.anytao.com">你必须知道的.NET</a>》1.5 &ldquo;玩转接口&rdquo;&nbsp; </li>
<li>《<a href="http://book.anytao.com">你必须知道的.NET</a>》7.4 &ldquo;面向抽象编程：接口和抽象类&rdquo; </li>
<li><a href="/allenlooplee/archive/2007/01/22/627386.html" title="http://www.cnblogs.com/allenlooplee/archive/2007/01/22/627386.html">http://www.cnblogs.com/allenlooplee/archive/2007/01/22/627386.html</a> </li>
</ul>
<p><span style="color: #800000; font-size: medium;">温故知新</span></p>
<p>[<a href="/anytao/archive/2007/04/06/must_net_00.html">开篇有益</a>] <br />[<a href="/anytao/archive/2007/04/07/must_net_01.html">第一回：恩怨情仇：is和as</a>] <br />[<a href="/anytao/archive/2007/04/12/must_net_02.html">第二回：对抽象编程：接口和抽象类</a>] <br />[<a href="/anytao/archive/2007/04/19/must_net_03.html">第三回：历史纠葛：特性和属性</a>] <br />[<a href="/anytao/archive/2007/04/24/must_net_04.html">第四回：后来居上：class和struct</a>] <br />[<a href="/anytao/archive/2007/04/28/must_net_05.html">第五回：深入浅出关键字---把new说透</a>] <br />[<a href="/anytao/archive/2007/05/04/must_net_06.html">第六回：深入浅出关键字---base和this</a>] <br />[<a href="/anytao/archive/2007/05/11/must_net_07.html">第七回：品味类型---从通用类型系统开始</a>] <br />[<a href="/anytao/archive/2007/05/23/must_net_08.html">第八回：品味类型---值类型与引用类型（上）－内存有理</a>] <br />[<a href="/anytao/archive/2007/05/28/must_net_09.html">第九回：品味类型---值类型与引用类型（中）－规则无边</a>] <br />[<a href="/anytao/archive/2007/06/18/must_net_10.html">第十回：品味类型---值类型与引用类型（下）－应用征途</a>] <br />[<a href="/anytao/archive/2007/07/06/must_net_11.html">第十一回：参数之惑---传递的艺术（上）</a>] <br />[<a href="/anytao/archive/2007/07/06/must_net_12.html">第十二回：参数之惑---传递的艺术（下）</a>] <br />[<a href="/anytao/archive/2007/07/22/must_net_13.html">第十三回：从Hello, world开始认识IL</a>] <br />[<a href="/anytao/archive/2007/08/22/must_net_14.html">第十四回：认识IL代码---从开始到现在</a>] <br />[<a href="/anytao/archive/2007/09/10/must_net_15.html">第十五回：继承本质论</a>] <br />[<a href="/anytao/archive/2007/10/01/must_net_16.html">第十六回：深入浅出关键字---using全接触</a>] <br />[<a href="/anytao/archive/2007/11/07/must_net_17.html">第十七回：貌合神离：覆写和重载</a>] <br />[<a href="/anytao/archive/2007/12/03/must_net_18.html">第十八回：对象创建始末（上）</a>] <br />[<a target="_blank" href="/anytao/archive/2007/12/07/must_net_19.html">第十九回：对象创建始末（下）</a>] <br />[<a href="/anytao/archive/2008/05/28/must_net_20.html">第二十回：学习方法论</a>] <br />[<a href="/anytao/archive/2008/07/31/must_net_21.html">第二十一回：认识全面的null</a>] <br />[<a href="/anytao/archive/2008/08/27/must_net_22.html">第二十二回：字符串驻留（上）---带着问题思考</a>] <br />[<a href="/anytao/archive/2008/11/02/must_net_23.html">第二十三回：品味细节，深入.NET的类型构造器</a>] <br />[<a href="/anytao/archive/2009/02/24/must_net_24.html">第二十四回：认识元数据和IL（上）</a>] <br />[<a href="/anytao/archive/2009/02/25/must_net_25.html">第二十五回：认识元数据和IL（中）</a>] <br />[<a href="/anytao/archive/2009/03/04/must_net_26.html">第二十六回：认识元数据和IL（下）</a>]</p><img src ="http://www.cnblogs.com/anytao/aggbug/1403550.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47969/" target="_blank">新浪邮箱大本营粉墨登场！Sina.cn开放注册</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item></channel></rss>