<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_lovecindywang  = lovecherry</title><subtitle type="text">未来是移动开发的天下@未来是云计算的天下</subtitle><id>http://feed.cnblogs.com/blog/u/64042/rss</id><updated>2012-06-02T06:57:13Z</updated><author><name>lovecindywang</name><uri>http://www.cnblogs.com/lovecindywang/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lovecindywang/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/64042/rss"/><entry><id>http://www.cnblogs.com/lovecindywang/archive/2012/06/02/2531952.html</id><title type="text">很久没有更新日志了</title><summary type="text">最近转了部门负责移动开发，自从接触了iOS之后，也成了一个果粉，喜欢苹果的iPad、iPhone也喜欢MacOS，iOS虽然封闭但非常吸引我，我感觉苹果的每一个细节都很完美，ObjectiveC语言也很简单实用，准备系统学习一下然后在这里写点自己的心得分享给大家。ObjC基本语法类和对象属性协议扩展字符串集合代码快内存管理运行时错误处理iOSTableViewController文件系统核心数据资...</summary><published>2012-06-02T06:47:00Z</published><updated>2012-06-02T06:47:00Z</updated><author><name>lovecindywang</name><uri>http://www.cnblogs.com/lovecindywang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lovecindywang/archive/2012/06/02/2531952.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lovecindywang/archive/2012/06/02/2531952.html"/><content type="html">&lt;p&gt;最近转了部门负责移动开发，自从接触了iOS之后，也成了一个果粉，喜欢苹果的iPad、iPhone也喜欢MacOS，iOS虽然封闭但非常吸引我，我感觉苹果的每一个细节都很完美，ObjectiveC语言也很简单实用，准备系统学习一下然后在这里写点自己的心得分享给大家。&lt;/p&gt;&lt;p&gt;ObjC&lt;/p&gt;&lt;ul&gt;&lt;li&gt;基本语法&lt;/li&gt;&lt;li&gt;类和对象&lt;/li&gt;&lt;li&gt;属性&lt;/li&gt;&lt;li&gt;协议&lt;/li&gt;&lt;li&gt;扩展&lt;/li&gt;&lt;li&gt;字符串&lt;/li&gt;&lt;li&gt;集合&lt;/li&gt;&lt;li&gt;代码快&lt;/li&gt;&lt;li&gt;内存管理&lt;/li&gt;&lt;li&gt;运行时&lt;/li&gt;&lt;li&gt;错误处理&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;iOS&lt;/p&gt;&lt;ul&gt;&lt;li&gt;TableView&lt;/li&gt;&lt;li&gt;Controller&lt;/li&gt;&lt;li&gt;文件系统&lt;/li&gt;&lt;li&gt;核心数据&lt;/li&gt;&lt;li&gt;资源&lt;/li&gt;&lt;li&gt;并发&lt;/li&gt;&lt;li&gt;多线程&lt;/li&gt;&lt;li&gt;定时器&lt;/li&gt;&lt;li&gt;联系人&lt;/li&gt;&lt;li&gt;位置服务&lt;/li&gt;&lt;li&gt;喜好&lt;/li&gt;&lt;li&gt;通知和推送&lt;/li&gt;&lt;li&gt;多语言&lt;/li&gt;&lt;li&gt;地图&lt;/li&gt;&lt;li&gt;声音&lt;/li&gt;&lt;li&gt;动画&lt;/li&gt;&lt;li&gt;图像&lt;/li&gt;&lt;li&gt;内购&lt;/li&gt;&lt;li&gt;文档&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;iOS5&lt;/p&gt;&lt;ul&gt;&lt;li&gt;ARC&lt;/li&gt;&lt;li&gt;storyboard&lt;/li&gt;&lt;li&gt;iCloud&lt;/li&gt;&lt;li&gt;PageViewController&lt;/li&gt;&lt;li&gt;UIKit自定义&lt;/li&gt;&lt;/ul&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;img src="http://www.cnblogs.com/lovecindywang/aggbug/2531952.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lovecindywang/archive/2012/06/02/2531952.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lovecindywang/archive/2012/03/07/2384387.html</id><title type="text">招聘 .NET/Java高级软件开发工程师（服务端）</title><summary type="text">工作职责：1、为IOS、Android、WindowsPhone等手机终端以及网站、Wap网站设计和开发后端程序。2、承担一定的后端程序性能优化和运维工作，在整个过程中持续改善性能以及为系统进行横向扩容。职位要求：1、至少四年以上.NET（C#）/Java开发经验，精通.NET 3.5、.NET 4框架，阅读过部分.NET源代码。2、熟悉服务端常见的一些开发技术，比如池、Socket、序列化、压缩、Wcf、Web服务、多线程等。3、熟悉服务端常见的一些优化技术，比如（分布式）缓存、队列、索引、异步操作等。4、具有很强的面向对象设计能力和业务分析能力，了解常见设计模式和测试方式，参与过架构设计和</summary><published>2012-03-07T14:43:00Z</published><updated>2012-03-07T14:43:00Z</updated><author><name>lovecindywang</name><uri>http://www.cnblogs.com/lovecindywang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lovecindywang/archive/2012/03/07/2384387.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lovecindywang/archive/2012/03/07/2384387.html"/><content type="html">&lt;p align="left"&gt;工作职责：&lt;/p&gt;&lt;p align="left"&gt;1、为IOS、Android、WindowsPhone等手机终端以及网站、Wap网站设计和开发后端程序。&lt;/p&gt;&lt;p align="left"&gt;2、承担一定的后端程序性能优化和运维工作，在整个过程中持续改善性能以及为系统进行横向扩容。&lt;/p&gt;&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;职位要求：&lt;/p&gt;&lt;p align="left"&gt;1、至少四年以上.NET（C#）/Java开发经验，精通.NET 3.5、.NET 4框架，阅读过部分.NET源代码。&lt;/p&gt;&lt;p align="left"&gt;2、熟悉服务端常见的一些开发技术，比如池、Socket、序列化、压缩、Wcf、Web服务、多线程等。&lt;/p&gt;&lt;p align="left"&gt;3、熟悉服务端常见的一些优化技术，比如（分布式）缓存、队列、索引、异步操作等。&lt;/p&gt;&lt;p align="left"&gt;4、具有很强的面向对象设计能力和业务分析能力，了解常见设计模式和测试方式，参与过架构设计和服务建模过程。&lt;/p&gt;&lt;p align="left"&gt;5、至少熟悉一个关系型数据库以及相关的数据库调优技巧。&lt;/p&gt;&lt;p align="left"&gt;6、参与开发过大数据量、大访问量的网站（非内网系统）并具有相应的优化经验。&lt;/p&gt;&lt;p align="left"&gt;（总之，你开发的服务端要能在千万级别到亿的数据量下，为各类客户端提供持续稳定的满足&amp;gt;100的TPS和&amp;lt;100ms响应速度的服务，当然这是一个持续优化的过程）&lt;/p&gt;&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;具有以下经验者优先考虑：&lt;/p&gt;&lt;p align="left"&gt;1、关注过各类开源项目（比如Netty、SuperSocket、Lucence），甚至参与或拥有开源项目。&lt;/p&gt;&lt;p align="left"&gt;2、熟悉Linux、熟悉除了C#/Java之外的其它语言，比如Java/C#、Python、PHP。&lt;/p&gt;&lt;p align="left"&gt;3、使用过诸如Mongodb、Redis、Cacendra、Hadoop等开源系统，或具有分布式应用架构经验。&lt;/p&gt;&lt;p align="left"&gt;4、具有互联网系统或社交系统开发经验，特别是使用或整合过诸如Google地图、百度地图等API，具有地图类应用开发经验。&lt;/p&gt;&lt;p align="left"&gt;5、了解移动终端（IOS、Android、WindowsPhone）的开发技术，或配合过进行相应的服务端开发。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;简历投递 &lt;a href="mailto:zhuye@5173.com"&gt;zhuye@5173.com&lt;/a&gt;&amp;nbsp;工作地点：上海普陀&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lovecindywang/aggbug/2384387.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lovecindywang/archive/2012/03/07/2384387.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lovecindywang/archive/2012/03/01/2376144.html</id><title type="text">Wcf扩展</title><summary type="text">ASP.NET MVC和WCF真是微软两个很棒的框架，设计的很好，可扩展性非常强，到处都是横切、管道。以前写过一篇MVC流程的文章，http://www.cnblogs.com/lovecindywang/archive/2010/12/02/1894740.html主要是使用了MVC的各种扩展。如下图列出了WCF的一些扩展点供参考，其实知道某个扩展点是干什么之后，搜索一下MSDN这个接口就一清二楚了：大部分情况下针对服务模型层进行扩展即可，我们可以看到就一个服务调用已经被完全打散了，细化到：调用的参数、调用什么方法、调用什么类型、类型怎么创建、消息的拦截、错误拦截、上下文初始化、服务承载。。</summary><published>2012-03-01T12:05:00Z</published><updated>2012-03-01T12:05:00Z</updated><author><name>lovecindywang</name><uri>http://www.cnblogs.com/lovecindywang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lovecindywang/archive/2012/03/01/2376144.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lovecindywang/archive/2012/03/01/2376144.html"/><content type="html">&lt;p&gt;ASP.NET MVC和WCF真是微软两个很棒的框架，设计的很好，可扩展性非常强，到处都是横切、管道。&lt;/p&gt;&lt;p&gt;以前写过一篇MVC流程的文章，&lt;a href="http://www.cnblogs.com/lovecindywang/archive/2010/12/02/1894740.html"&gt;http://www.cnblogs.com/lovecindywang/archive/2010/12/02/1894740.html&lt;/a&gt;主要是使用了MVC的各种扩展。&lt;/p&gt;&lt;p&gt;如下图列出了WCF的一些扩展点供参考，其实知道某个扩展点是干什么之后，搜索一下MSDN这个接口就一清二楚了：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201203/201203012004334141.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="wcf扩展" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201203/201203012004364858.jpg" alt="wcf扩展" width="1073" height="793" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;大部分情况下针对服务模型层进行扩展即可，我们可以看到就一个服务调用已经被完全打散了，细化到：&lt;/p&gt;&lt;p&gt;调用的参数、调用什么方法、调用什么类型、类型怎么创建、消息的拦截、错误拦截、上下文初始化、服务承载。。。。&lt;/p&gt;&lt;p&gt;如果对协议信道层进行扩展（和服务模型层不同，其实主要是写自己的抽象类实现而不是实现接口加入管道或横切）的话，具有完全的自主定义传输内容的同时又可以不去考虑一些细节问题。&lt;/p&gt;&lt;p&gt;有一个哥们总结了&lt;a href="http://blogs.msdn.com/b/carlosfigueira/archive/2011/03/14/wcf-extensibility.aspx" target="_blank"&gt;一系列文章&lt;/a&gt;，非常不错值得一看。一篇短短的博客，信息量不少，希望对大家有帮助。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lovecindywang/aggbug/2376144.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lovecindywang/archive/2012/03/01/2376144.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lovecindywang/archive/2012/02/10/2345895.html</id><title type="text">【翻译】C#编程语言和JAVA编程语言的比较（下）</title><summary type="text">原文地址：http://www.25hoursaday.com/CsharpVsJava.html 6、集合 许多有名的编程语言都会包含一个集合框架，框架一般由各种用于保存数据的数据结构和配套的操作对象的算法构成。集合框架的优势是让开发者可以不用写数据结构和排序算法，把精力放在真正的业务逻辑上。还有就是可以让不同的项目保持一致性，新的开发者也少了很多学习曲线。 C#集合框架大多位...</summary><published>2012-02-10T09:52:00Z</published><updated>2012-02-10T09:52:00Z</updated><author><name>lovecindywang</name><uri>http://www.cnblogs.com/lovecindywang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lovecindywang/archive/2012/02/10/2345895.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lovecindywang/archive/2012/02/10/2345895.html"/><content type="html">&lt;p&gt;原文地址：&lt;a title="http://www.25hoursaday.com/CsharpVsJava.html" href="http://www.25hoursaday.com/CsharpVsJava.html"&gt;http://www.25hoursaday.com/CsharpVsJava.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;6、集合&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;许多有名的编程语言都会包含一个集合框架，框架一般由各种用于保存数据的数据结构和配套的操作对象的算法构成。集合框架的优势是让开发者可以不用写数据结构和排序算法，把精力放在真正的业务逻辑上。还有就是可以让不同的项目保持一致性，新的开发者也少了很多学习曲线。&lt;/p&gt;  &lt;p&gt;C#集合框架大多位于&lt;code&gt;System.Collections和&lt;code&gt;System.Collections.Generic命名空间。&lt;code&gt;Systems.Collections命名空间包含了表示抽象数据类型的接口和抽象类，比如IList, IEnumerable, IDictionary, ICollection, 和 CollectionBase，只要数据结构从抽象数据类型派生，开发者无需关心其内部如何实现。&lt;code&gt;System.Collections命名空间还包含了很多数据结构的具体实现，包括ArrayList, Stack, Queue, HashTable 和SortedList。这四种结构都提供了同步包装，可以在多线程程序中线程安全。&lt;code&gt;System.Collections.Generic命名空间实现了&lt;code&gt;System.Collections空间中主要数据结构的泛型版本，包括泛型的List&amp;lt;T&amp;gt;, Stack&amp;lt;T&amp;gt;,Queue&amp;lt;T&amp;gt;, Dictionary&amp;lt;K,T&amp;gt; 和SortedDictionary&amp;lt;K,T&amp;gt;类。&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;Java集合框架则在&lt;code&gt;java.util包中包含许多类和接口。&lt;code&gt;java.util包也同样支持泛型，并没有使用新的命名空间来放置泛型类型。Java集合框架和C#相似，不过可以认为是C#集合框架的超集，因为它实现了一些其它特性。&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;em&gt;注意：后面作者的话我就不翻译了，因为他提到的Java中有，而C#中没有的集合在.NET 3.5和.NET 4.0中都已经支持&lt;/em&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;7、goto&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;和Java不同，C#包含的goto可以用来在代码中进行跳转，尽管goto被嘲笑，但是有的时候还是可以使用goto来减少代码重复并增加可读性。goto语句第二个用处是可以重用异常，因为异常抛出是无法跨越方法边界的。&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;em&gt;注意：在C#中goto无法跳转到语句块&lt;/em&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Net.Sockets; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; GotoSample{&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; num_tries = 0;&lt;br/&gt;    &lt;br/&gt;       retry: &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;try&lt;/span&gt;{             &lt;br/&gt;&lt;br/&gt;        num_tries++;    &lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Attempting to connect to network. Number of tries =&amp;quot;&lt;/span&gt; + num_tries);&lt;br/&gt;&lt;br/&gt;        &lt;span class="rem"&gt;//Attempt to connect to a network times out &lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;//or some some other network connection error that &lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;//can be recovered from&lt;/span&gt;&lt;br/&gt;       &lt;br/&gt;        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; SocketException(); &lt;br/&gt;&lt;br/&gt;    }&lt;span class="kwrd"&gt;catch&lt;/span&gt;(SocketException){&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;(num_tries &amp;lt; 5)&lt;br/&gt;        &lt;span class="kwrd"&gt;goto&lt;/span&gt; retry;                 &lt;br/&gt;    }       &lt;br/&gt;   &lt;br/&gt;   }&lt;span class="rem"&gt;/* Main(string[]) */&lt;/span&gt; &lt;br/&gt;&lt;br/&gt;}&lt;span class="rem"&gt;//GotoSample&lt;/span&gt;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;8、虚方法&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;面向对象的一个主要特点就是多态。多态可以让我们和继承体系中的泛化类型而不是实际类型打交道。也就是一般在基类中实现的方法在派生类中重写，我们即使持有基类类型的引用，但是其指向派生类型，在运行时而不是编译时动态绑定的方法叫做虚方法。在Java中所有的方法都是虚方法，而在C#中，必须通过virtual关键字显式指定方法为虚方法，默认不是虚方法。同样可以用override关键字在子类中重写虚方法或使用new关键字隐藏基类方法。在Java中可以通过标记方法为final关键字让方法不能被派生类重写，在C#中可以不标记virtual来实现。主要区别是，如果派生类也实现了相同方法，C#的可以通过把引用指向基类调用到基类的方法，而在Java中如果基类实现了final方法，派生类不允许再有同名的方法。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Parent{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoStuff(&lt;span class="kwrd"&gt;string&lt;/span&gt; str){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;In Parent.DoStuff: &amp;quot;&lt;/span&gt; + str); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Child: Parent{&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoStuff(&lt;span class="kwrd"&gt;int&lt;/span&gt; n){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;In Child.DoStuff: &amp;quot;&lt;/span&gt; + n);    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoStuff(&lt;span class="kwrd"&gt;string&lt;/span&gt; str){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;In Child.DoStuff: &amp;quot;&lt;/span&gt; + str);  &lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; VirtualTest{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    Child ch = &lt;span class="kwrd"&gt;new&lt;/span&gt; Child(); &lt;br/&gt;&lt;br/&gt;    ch.DoStuff(100); &lt;br/&gt;    ch.DoStuff(&lt;span class="str"&gt;&amp;quot;Test&amp;quot;&lt;/span&gt;); &lt;br/&gt;&lt;br/&gt;    ((Parent) ch).DoStuff(&lt;span class="str"&gt;&amp;quot;Second Test&amp;quot;&lt;/span&gt;); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;span class="rem"&gt;//VirtualTest&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;OUTPUT:&lt;br/&gt;In Child.DoStuff: 100&lt;br/&gt;In Child.DoStuff: Test&lt;br/&gt;In Parent.DoStuff: Second Test&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;Java Code&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Parent{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoStuff(String str){&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;&amp;quot;In Parent.DoStuff: &amp;quot;&lt;/span&gt; + str);    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Child extends Parent{&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoStuff(&lt;span class="kwrd"&gt;int&lt;/span&gt; n){&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;&amp;quot;In Child.DoStuff: &amp;quot;&lt;/span&gt; + n);   &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoStuff(String str){&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;&amp;quot;In Child.DoStuff: &amp;quot;&lt;/span&gt; + str); &lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; VirtualTest{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args){&lt;br/&gt;&lt;br/&gt;    Child ch = &lt;span class="kwrd"&gt;new&lt;/span&gt; Child(); &lt;br/&gt;&lt;br/&gt;    ch.DoStuff(100); &lt;br/&gt;    ch.DoStuff(&lt;span class="str"&gt;&amp;quot;Test&amp;quot;&lt;/span&gt;); &lt;br/&gt;&lt;br/&gt;    ((Parent) ch).DoStuff(&lt;span class="str"&gt;&amp;quot;Second Test&amp;quot;&lt;/span&gt;); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;span class="rem"&gt;//VirtualTest&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;OUTPUT:&lt;br/&gt;In Child.DoStuff: 100&lt;br/&gt;In Child.DoStuff: Test&lt;br/&gt;In Child.DoStuff: Second Test&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;C#的例子可以通过把基类DoStuff(string) 方法标记为&lt;code&gt;virtual子类方法标记为&lt;code&gt;override关键字来实现和Java相同输出：&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;# Code&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Parent{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoStuff(&lt;span class="kwrd"&gt;string&lt;/span&gt; str){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;In Parent.DoStuff: &amp;quot;&lt;/span&gt; + str); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Child: Parent{&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoStuff(&lt;span class="kwrd"&gt;int&lt;/span&gt; n){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;In Child.DoStuff: &amp;quot;&lt;/span&gt; + n);    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoStuff(&lt;span class="kwrd"&gt;string&lt;/span&gt; str){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;In Child.DoStuff: &amp;quot;&lt;/span&gt; + str);  &lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; VirtualTest{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    Child ch = &lt;span class="kwrd"&gt;new&lt;/span&gt; Child(); &lt;br/&gt;&lt;br/&gt;    ch.DoStuff(100); &lt;br/&gt;    ch.DoStuff(&lt;span class="str"&gt;&amp;quot;Test&amp;quot;&lt;/span&gt;); &lt;br/&gt;&lt;br/&gt;    ((Parent) ch).DoStuff(&lt;span class="str"&gt;&amp;quot;Second Test&amp;quot;&lt;/span&gt;); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;span class="rem"&gt;//VirtualTest&lt;/span&gt;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;如上例子可以修改子类的DoStuff(string)方法为如下以得到之前的结果：&lt;/p&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoStuff(&lt;span class="kwrd"&gt;string&lt;/span&gt; str)&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;9、文件IO&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;两种语言都通过Stream类支持IO操作，如下例子把input.txt的内容复制到output.txt中。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO; &lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; FileIOTest {&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    FileStream inputFile  = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileStream(&lt;span class="str"&gt;&amp;quot;input.txt&amp;quot;&lt;/span&gt;, FileMode.Open);&lt;br/&gt;    FileStream outputFile = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileStream(&lt;span class="str"&gt;&amp;quot;output.txt&amp;quot;&lt;/span&gt;, FileMode.Open);&lt;br/&gt;&lt;br/&gt;        StreamReader sr     = &lt;span class="kwrd"&gt;new&lt;/span&gt; StreamReader(inputFile);&lt;br/&gt;        StreamWriter sw     = &lt;span class="kwrd"&gt;new&lt;/span&gt; StreamWriter(outputFile);&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    String str;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt;((str = sr.ReadLine())!= &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br/&gt;        sw.Write(str);&lt;br/&gt;&lt;br/&gt;        sr.Close();&lt;br/&gt;        sw.Close();&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;span class="rem"&gt;//FileIOTest&lt;/span&gt;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;Java Code&lt;br/&gt;import java.io.*;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; FileIO{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args) throws IOException {&lt;br/&gt;&lt;br/&gt;    File inputFile  = &lt;span class="kwrd"&gt;new&lt;/span&gt; File(&lt;span class="str"&gt;&amp;quot;input.txt&amp;quot;&lt;/span&gt;);&lt;br/&gt;    File outputFile = &lt;span class="kwrd"&gt;new&lt;/span&gt; File(&lt;span class="str"&gt;&amp;quot;output.txt&amp;quot;&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;        FileReader &lt;span class="kwrd"&gt;in&lt;/span&gt;     = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileReader(inputFile);&lt;br/&gt;    BufferedReader br = &lt;span class="kwrd"&gt;new&lt;/span&gt; BufferedReader(&lt;span class="kwrd"&gt;in&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;        FileWriter &lt;span class="kwrd"&gt;out&lt;/span&gt;    = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileWriter(outputFile);&lt;br/&gt;    BufferedWriter bw = &lt;span class="kwrd"&gt;new&lt;/span&gt; BufferedWriter(&lt;span class="kwrd"&gt;out&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    String str;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt;((str = br.readLine())!= &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br/&gt;        bw.write(str);&lt;br/&gt;&lt;br/&gt;        br.close();&lt;br/&gt;        bw.close();&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;span class="rem"&gt;//FileIOTest&lt;/span&gt;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;10、对象序列化&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;对象持久化或叫序列化是通过诸如文件或网络读写对象的能力。如果在使用程序的时候对象的状态必须保存下来，那么对象持久化就很有用。有的时候以简单文本形式保存数据不够，以DBMS保存数据又劳师动众了，那么可以使用序列化直接保存，还有的时候可以使用序列化来传输类型。C#中可序列化类型标记&lt;code&gt;[Serializable]特性。如果C#的类的一些成员不需要在运行时序列化，可以标记&lt;code&gt;[NonSerialized]特性。这些字段通常用于计算或是临时的值，不需要保存下来。C#提供了两种格式来序列化类，XML或二进制格式，前者对于人来说更可读，后者更高效。当然我们也可以通过实现&lt;code&gt;ISerializable接口实现自定义的序列化方式。&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;在Java中，对象序列化需要实现&lt;code&gt;Serializable接口，而&lt;code&gt;transient关键字用于标记不需要序列化的成员。默认情况下，Java支持序列化对象到二进制格式，但是提供了重写标准序列化过程的方式。需要重写默认序列化的对象需要实现如下方法签名：&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException;&lt;/p&gt;&lt;p&gt;private void writeObject(java.io.ObjectOutputStream stream) throws IOException&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;由于上面的方法是private的，使用readObject和writeObject来实现自定义序列化的话没有要实现的接口，对于需要公开访问的方法的类实现自定义序列化可以使用&lt;code&gt;java.io.Externalizable接口，指定readExternal() 和writeExternal()。&lt;/code&gt;&lt;/p&gt;C# Code&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Reflection;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Runtime.Serialization;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Runtime.Serialization.Formatters.Binary;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Runtime.Serialization.Formatters.Soap;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;[Serializable]&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; SerializeTest{&lt;br/&gt;&lt;br/&gt;    [NonSerialized]&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; x; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; y; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; SerializeTest(&lt;span class="kwrd"&gt;int&lt;/span&gt; a, &lt;span class="kwrd"&gt;int&lt;/span&gt; b){&lt;br/&gt;&lt;br/&gt;    x = a; &lt;br/&gt;    y = b; &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; String ToString(){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;{x=&amp;quot;&lt;/span&gt; + x + &lt;span class="str"&gt;&amp;quot;, y=&amp;quot;&lt;/span&gt; + y + &lt;span class="str"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(String[] args){&lt;br/&gt;&lt;br/&gt;    SerializeTest st = &lt;span class="kwrd"&gt;new&lt;/span&gt; SerializeTest(66, 61); &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Before Binary Write := &amp;quot;&lt;/span&gt; + st);&lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\n Writing SerializeTest object to disk&amp;quot;&lt;/span&gt;);&lt;br/&gt;    Stream output  = File.Create(&lt;span class="str"&gt;&amp;quot;serialized.bin&amp;quot;&lt;/span&gt;);&lt;br/&gt;    BinaryFormatter bwrite = &lt;span class="kwrd"&gt;new&lt;/span&gt; BinaryFormatter(); &lt;br/&gt;    bwrite.Serialize(output, st); &lt;br/&gt;    output.Close(); &lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\n Reading SerializeTest object from disk\n&amp;quot;&lt;/span&gt;);&lt;br/&gt;    Stream input  = File.OpenRead(&lt;span class="str"&gt;&amp;quot;serialized.bin&amp;quot;&lt;/span&gt;);&lt;br/&gt;    BinaryFormatter bread = &lt;span class="kwrd"&gt;new&lt;/span&gt; BinaryFormatter(); &lt;br/&gt;    SerializeTest fromdisk = (SerializeTest)bread.Deserialize(input); &lt;br/&gt;    input.Close(); &lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* x will be 0 because it won't be read from disk since non-serialized */&lt;/span&gt; &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;After Binary Read := &amp;quot;&lt;/span&gt; + fromdisk);&lt;br/&gt;&lt;br/&gt;    &lt;br/&gt;    st = &lt;span class="kwrd"&gt;new&lt;/span&gt; SerializeTest(19, 99);  &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\n\nBefore SOAP(XML) Serialization := &amp;quot;&lt;/span&gt; + st);&lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\n Writing SerializeTest object to disk&amp;quot;&lt;/span&gt;);&lt;br/&gt;    output  = File.Create(&lt;span class="str"&gt;&amp;quot;serialized.xml&amp;quot;&lt;/span&gt;);&lt;br/&gt;    SoapFormatter swrite = &lt;span class="kwrd"&gt;new&lt;/span&gt; SoapFormatter(); &lt;br/&gt;    swrite.Serialize(output, st); &lt;br/&gt;    output.Close(); &lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\n Reading SerializeTest object from disk\n&amp;quot;&lt;/span&gt;);&lt;br/&gt;    input  = File.OpenRead(&lt;span class="str"&gt;&amp;quot;serialized.xml&amp;quot;&lt;/span&gt;);&lt;br/&gt;    SoapFormatter sread = &lt;span class="kwrd"&gt;new&lt;/span&gt; SoapFormatter(); &lt;br/&gt;    fromdisk = (SerializeTest)sread.Deserialize(input); &lt;br/&gt;    input.Close(); &lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* x will be 0 because it won't be read from disk since non-serialized */&lt;/span&gt; &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;After SOAP(XML) Serialization := &amp;quot;&lt;/span&gt; + fromdisk);&lt;br/&gt;&lt;br/&gt;    &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\n\nPrinting XML Representation of Object&amp;quot;&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    XmlDocument doc = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlDocument(); &lt;br/&gt;    doc.Load(&lt;span class="str"&gt;&amp;quot;serialized.xml&amp;quot;&lt;/span&gt;); &lt;br/&gt;    Console.WriteLine(doc.OuterXml);&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt;import java.io.*; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; SerializeTest implements Serializable{&lt;br/&gt;&lt;br/&gt;    transient &lt;span class="kwrd"&gt;int&lt;/span&gt; x; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; y; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; SerializeTest(&lt;span class="kwrd"&gt;int&lt;/span&gt; a, &lt;span class="kwrd"&gt;int&lt;/span&gt; b){&lt;br/&gt;&lt;br/&gt;    x = a; &lt;br/&gt;    y = b; &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; String toString(){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;{x=&amp;quot;&lt;/span&gt; + x + &lt;span class="str"&gt;&amp;quot;, y=&amp;quot;&lt;/span&gt; + y + &lt;span class="str"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args) throws Exception{&lt;br/&gt;&lt;br/&gt;    SerializeTest st = &lt;span class="kwrd"&gt;new&lt;/span&gt; SerializeTest(66, 61); &lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;&amp;quot;Before Write := &amp;quot;&lt;/span&gt; + st);&lt;br/&gt;&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;&amp;quot;\n Writing SerializeTest object to disk&amp;quot;&lt;/span&gt;);&lt;br/&gt;    FileOutputStream &lt;span class="kwrd"&gt;out&lt;/span&gt;  = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileOutputStream(&lt;span class="str"&gt;&amp;quot;serialized.txt&amp;quot;&lt;/span&gt;);&lt;br/&gt;    ObjectOutputStream so = &lt;span class="kwrd"&gt;new&lt;/span&gt; ObjectOutputStream(&lt;span class="kwrd"&gt;out&lt;/span&gt;);    &lt;br/&gt;    so.writeObject(st);&lt;br/&gt;    so.flush();&lt;br/&gt;&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;&amp;quot;\n Reading SerializeTest object from disk\n&amp;quot;&lt;/span&gt;);&lt;br/&gt;    FileInputStream &lt;span class="kwrd"&gt;in&lt;/span&gt;     = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileInputStream(&lt;span class="str"&gt;&amp;quot;serialized.txt&amp;quot;&lt;/span&gt;);&lt;br/&gt;    ObjectInputStream si   = &lt;span class="kwrd"&gt;new&lt;/span&gt; ObjectInputStream(&lt;span class="kwrd"&gt;in&lt;/span&gt;); &lt;br/&gt;    SerializeTest fromdisk = (SerializeTest)si.readObject();&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* x will be 0 because it won't be read from disk since transient */&lt;/span&gt; &lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;&amp;quot;After Read := &amp;quot;&lt;/span&gt; + fromdisk);&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;输出结果：&lt;/p&gt;&lt;p&gt;Before Write := {x=66, y=61}&lt;/p&gt;&lt;p&gt;Writing SerializeTest object to disk&lt;/p&gt;&lt;p&gt;Reading SerializeTest object from disk&lt;/p&gt;&lt;p&gt;After Read := {x=0, y=61}&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;11、文档生成&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;C#和Java都提供了从源文件提取特殊格式的注释然后集中到一个文档中。这些注释一般是API规范，这是一种非常有用的方式来生成类库文档。生成的文档也可以在设计者、开发者和QA之间分发。Javadoc是一种非常有用的工具用于从源代码提取API文档。Javadoc从源代码注释中提取内容生成HTML文档。可以生成的描述信息包括包、类、成员级别。可以在类或成员变量的描述中提供对其它类或类成员的引用。&lt;/p&gt;&lt;p&gt;Javadoc允许方法有如下信息：&lt;/p&gt;&lt;p&gt;1）描述方法&lt;/p&gt;&lt;p&gt;2）方法抛出的异常&lt;/p&gt;&lt;p&gt;3）方法接收的参数&lt;/p&gt;&lt;p&gt;4）方法的返回值&lt;/p&gt;&lt;p&gt;5）关联的方法和成员&lt;/p&gt;&lt;p&gt;6）API是否被弃用&lt;/p&gt;&lt;p&gt;7）方法首次提供的时间&lt;/p&gt;&lt;p&gt;废弃信息对于编译器也有用，如果在编译的时候编译器发现调用了废弃的方法可以给予警告。&lt;/p&gt;&lt;p&gt;Javadoc自动提供如下信息：&lt;/p&gt;&lt;p&gt;1）继承的API&lt;/p&gt;&lt;p&gt;2）派生类列表&lt;/p&gt;&lt;p&gt;3）实现的类或借口&lt;/p&gt;&lt;p&gt;4）类序列化格式&lt;/p&gt;&lt;p&gt;5）包继承层次&lt;/p&gt;&lt;p&gt;由于Java生成HTML文档，可以在Javadoc注释中使用HTML。如下是一个例子：&lt;/p&gt;Java Code&lt;br/&gt;&lt;br/&gt;&lt;span class="rem"&gt;/**&lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt; * Calculates the square of a number. &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt; * @param num the number to calculate. &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt; * @return the square of the number. &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt; * @exception NumberTooBigException this occurs if the square of the number &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt; * is too big to be stored in an int. &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt; */&lt;/span&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; square(&lt;span class="kwrd"&gt;int&lt;/span&gt; num) throws NumberTooBigException{}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;C#使用XML作为文档格式。生成的文档是XML文件，包含了用于提供的元数据以及少量自动生成的信息。C#的XML文档在生成的时候不会包含有关继承API列表、派生类或实现接口等元数据。&lt;/p&gt;&lt;p&gt;XML格式的主要优势是可以以各种方式来用。可以用XSLT样式来吧生成ASCII文本、HTML等。也可以作为一些工具的数据源来生成特殊的文档。&lt;/p&gt;&lt;p&gt;如下是C# XML文档的例子：&lt;/p&gt;C# Code&lt;br/&gt;&lt;br/&gt;&lt;span class="rem"&gt;///&amp;lt;summary&amp;gt;Calculates the square of a number.&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;///&amp;lt;param name=&amp;quot;num&amp;quot;&amp;gt;The number to calculate.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;///&amp;lt;return&amp;gt;The square of the number. &amp;lt;/return&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;///&amp;lt;exception&amp;gt;NumberTooBigException - this occurs if the square of the number &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;///is too big to be stored in an int. &amp;lt;/exception&amp;gt;&lt;/span&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; square(&lt;span class="kwrd"&gt;int&lt;/span&gt; num){}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;12、单个文件中的多个类&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;两种语言都可以在单个文件中定义多个类，但是有区别。在Java中，一个原文件中只可以有一个public访问的类并且类名需要和不带扩展名的源文件名保持一致。C#则对一个文件有多少个public类以及文件名是否和类名一致都没有限制。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;13、导入类库&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;在应用程序中使用类库有两个步骤，首先需要在源文件中使用using或import关键字来引用空间或包，其次需要告诉编译器哪里有需要的类库。对于Java来说指定类库位置可以使用CLASSPATH环境变量或使用-classpath编译器选项，对于C#则在编译的时候指定/r开关。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;14、事件&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;所谓事件驱动编程就是一个对象可以进行注册使得自己在别的独享状态修改或发生某个事件的时候被通知。事件驱动编程也被称作发布订阅模型或观察者设计模式，并且在图形用户接口GUI编程上特别常见。Java和C#都有自己的机制实现事件。典型的发布订阅模型是一个一对多的关系，也就是一个发布者对应多个订阅者。订阅者在发布者这里注册要调用的方法，订阅者通过内部集合保存订阅者对象。如果订阅者感兴趣的状态改变，发布者会调用一个方法遍历订阅者集合调用回调方法。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;在Java中没有通用的机制来实现事件，而是采用了GUI类中使用的设计模式。事件一般是java.util.EventObject类的子类，这个类具有设置或获取事件来源的方法。在Java中订阅者一般实现接口，并且以Listener结尾，比如MouseListener, ActionListener, KeyListener，包含一个回调方法用于在事件发生的时候被发布者调用。发布者一般包含add和Listerner名字组合而成的方法用于添加注册的订阅者，比如addMouseListener, addActionListener, addKeyListener。发布者还包含用于移除订阅者的方法。这些结构构成了Java程序中的事件驱动模型。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;C#使用委托来提供发布订阅模型的显式支持，事件一般是&lt;code&gt;System.EventArgs类的子类。发布者具有protected的方法并以On为前缀，比如OnClick, OnClose, OnInit，在某个事件发生的时候调用这个方法，这个方法然后会调用委托并且传入EventArgs对象的实例作为参数。这个方法作为protected的话派生类就可以直接调用，无需注册委托。订阅者的方法接收和事件委托相同的返回类型和参数。事件委托一般接收两个参数，一个Object表示事件的源，一个EventArgs类表示发生的事件，并且委托是void返回值。在C#中event用于自动指定事件驱动中回调的订阅者委托。在编译的时候，编译器会增加+=和-=，等同于Java的注册和移除订阅者的方法。&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;code&gt;如下例子演示了一个类生成20个随机数，然后在遇到偶数的时候触发事件。&lt;/code&gt;&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; EvenNumberEvent: EventArgs{&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* HACK: fields are typically private, but making this internal so it&lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;     * can be accessed from other classes. In practice should use properties.&lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;     */&lt;/span&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; number; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; EvenNumberEvent(&lt;span class="kwrd"&gt;int&lt;/span&gt; number):&lt;span class="kwrd"&gt;base&lt;/span&gt;(){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.number = number;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Publisher{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; EvenNumberSeenHandler(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e); &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;event&lt;/span&gt; EvenNumberSeenHandler EvenNumHandler; &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnEvenNumberSeen(&lt;span class="kwrd"&gt;int&lt;/span&gt; num){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(EvenNumHandler!= &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br/&gt;        EvenNumHandler(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; EvenNumberEvent(num));&lt;br/&gt;    }&lt;br/&gt;    &lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//generates 20 random numbers between 1 and 20 then causes and &lt;/span&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//event to occur if the current number is even. &lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; RunNumbers(){&lt;br/&gt;    &lt;br/&gt;    Random r = &lt;span class="kwrd"&gt;new&lt;/span&gt; Random((&lt;span class="kwrd"&gt;int&lt;/span&gt;) DateTime.Now.Ticks); &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i=0; i &amp;lt; 20; i++){     &lt;br/&gt;        &lt;span class="kwrd"&gt;int&lt;/span&gt; current = (&lt;span class="kwrd"&gt;int&lt;/span&gt;) r.Next(20); &lt;br/&gt;&lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Current number is:&amp;quot;&lt;/span&gt; + current);&lt;br/&gt;&lt;br/&gt;        &lt;span class="rem"&gt;//check if number is even and if so initiate callback call&lt;/span&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;((current % 2) == 0)&lt;br/&gt;        OnEvenNumberSeen(current);&lt;br/&gt;&lt;br/&gt;    }&lt;span class="rem"&gt;//for&lt;/span&gt;&lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;}&lt;span class="rem"&gt;//Publisher&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; EventTest{&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//callback function that will be called when even number is seen&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; EventHandler(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e){&lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\t\tEven Number Seen:&amp;quot;&lt;/span&gt; + ((EvenNumberEvent)e).number);&lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    Publisher pub = &lt;span class="kwrd"&gt;new&lt;/span&gt; Publisher(); &lt;br/&gt;    &lt;br/&gt;    &lt;span class="rem"&gt;//register the callback/subscriber &lt;/span&gt;&lt;br/&gt;    pub.EvenNumHandler += &lt;span class="kwrd"&gt;new&lt;/span&gt; Publisher.EvenNumberSeenHandler(EventHandler); &lt;br/&gt;    &lt;br/&gt;    pub.RunNumbers(); &lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//unregister the callback/subscriber &lt;/span&gt;&lt;br/&gt;    pub.EvenNumHandler -= &lt;span class="kwrd"&gt;new&lt;/span&gt; Publisher.EvenNumberSeenHandler(EventHandler); &lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;Java Code&lt;br/&gt;import java.util.*;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; EvenNumberEvent extends EventObject{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; number; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; EvenNumberEvent(Object source, &lt;span class="kwrd"&gt;int&lt;/span&gt; number){&lt;br/&gt;    &lt;br/&gt;    super(source); &lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.number = number;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;interface&lt;/span&gt; EvenNumberSeenListener{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; evenNumberSeen(EvenNumberEvent ene); &lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Publisher{&lt;br/&gt;&lt;br/&gt;    Vector subscribers = &lt;span class="kwrd"&gt;new&lt;/span&gt; Vector(); &lt;br/&gt;    &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnEvenNumberSeen(&lt;span class="kwrd"&gt;int&lt;/span&gt; num){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i=0, size = subscribers.size(); i &amp;lt; size; i++)&lt;br/&gt;        ((EvenNumberSeenListener)subscribers.get(i)).evenNumberSeen(&lt;span class="kwrd"&gt;new&lt;/span&gt; EvenNumberEvent(&lt;span class="kwrd"&gt;this&lt;/span&gt;, num));&lt;br/&gt;    }&lt;br/&gt;    &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; addEvenNumberEventListener(EvenNumberSeenListener ensl){&lt;br/&gt;&lt;br/&gt;    subscribers.add(ensl); &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; removeEvenNumberEventListener(EvenNumberSeenListener ensl){&lt;br/&gt;&lt;br/&gt;    subscribers.remove(ensl); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//generates 20 random numbers between 1 and 20 then causes and &lt;/span&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//event to occur if the current number is even. &lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; RunNumbers(){&lt;br/&gt;    &lt;br/&gt;    Random r = &lt;span class="kwrd"&gt;new&lt;/span&gt; Random(System.currentTimeMillis()); &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i=0; i &amp;lt; 20; i++){     &lt;br/&gt;        &lt;span class="kwrd"&gt;int&lt;/span&gt; current = (&lt;span class="kwrd"&gt;int&lt;/span&gt;) r.nextInt() % 20; &lt;br/&gt;&lt;br/&gt;        System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;&amp;quot;Current number is:&amp;quot;&lt;/span&gt; + current);&lt;br/&gt;&lt;br/&gt;        &lt;span class="rem"&gt;//check if number is even and if so initiate callback call&lt;/span&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;((current % 2) == 0)&lt;br/&gt;        OnEvenNumberSeen(current);&lt;br/&gt;&lt;br/&gt;    }&lt;span class="rem"&gt;//for&lt;/span&gt;&lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;span class="rem"&gt;//Publisher&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; EventTest implements EvenNumberSeenListener{&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//callback function that will be called when even number is seen&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; evenNumberSeen(EvenNumberEvent e){&lt;br/&gt;&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;&amp;quot;\t\tEven Number Seen:&amp;quot;&lt;/span&gt; + ((EvenNumberEvent)e).number);&lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args){&lt;br/&gt;&lt;br/&gt;    EventTest et = &lt;span class="kwrd"&gt;new&lt;/span&gt; EventTest();&lt;br/&gt;&lt;br/&gt;    Publisher pub = &lt;span class="kwrd"&gt;new&lt;/span&gt; Publisher(); &lt;br/&gt;    &lt;br/&gt;    &lt;span class="rem"&gt;//register the callback/subscriber &lt;/span&gt;&lt;br/&gt;    pub.addEvenNumberEventListener(et); &lt;br/&gt;    &lt;br/&gt;    pub.RunNumbers(); &lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//unregister the callback/subscriber &lt;/span&gt;&lt;br/&gt;    pub.removeEvenNumberEventListener(et); &lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;运行结果&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Current number is:19   &lt;br /&gt;Current number is:15   &lt;br /&gt;Current number is:1   &lt;br /&gt;Current number is:1   &lt;br /&gt;Current number is:-9   &lt;br /&gt;Current number is:-17   &lt;br /&gt;Current number is:-1   &lt;br /&gt;Current number is:-18   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Even Number Seen:-18   &lt;br /&gt;Current number is:0   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Even Number Seen:0   &lt;br /&gt;Current number is:1   &lt;br /&gt;Current number is:-2   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Even Number Seen:-2   &lt;br /&gt;Current number is:-9   &lt;br /&gt;Current number is:-4   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Even Number Seen:-4   &lt;br /&gt;Current number is:17   &lt;br /&gt;Current number is:-7   &lt;br /&gt;Current number is:1   &lt;br /&gt;Current number is:0   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Even Number Seen:0   &lt;br /&gt;Current number is:15   &lt;br /&gt;Current number is:-10   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Even Number Seen:-10   &lt;br /&gt;Current number is:-9 &lt;/p&gt;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;15、跨语言互操作&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;跨语言互操作是在一个语言中访问另一个语言构造的能力。在Java中有很多跨语言互操作的方式。首先JNI机制允许Java程序调用C或C++甚至汇编语言写的本机方法。本机方法可以使用JNI来访问Java的特性，比如调用Java语言方法，初始化和修改Java类，抛出和捕获异常，进行运行时类型检查，动态加载Java类。要创建JNI程序可以进行如下步骤：&lt;/p&gt;&lt;p&gt;1）创建Java程序，把包含本机方法的声明标记为native方法&lt;/p&gt;&lt;p&gt;2）写一个main方法加载步骤6的类库，然后使用本机方法&lt;/p&gt;&lt;p&gt;3）使用javac编译器编译包含native方法和main的类&lt;/p&gt;&lt;p&gt;4）使用javah编译器和-jni开关来生产头文件和本地方法&lt;/p&gt;&lt;p&gt;5) 使用你选择的语言写本机方法&lt;/p&gt;&lt;p&gt;6) 把头文件和本机源文件编译到共享类库中，比如Windows的dll或UNIX的.so&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Java还可以通过Java IDL来和CORBA的分布式对象交互。CORBA应用程序一般由对象请求代理ORB、客户端和服务端构成。ORB负责匹配请求客户端到服务端，使用对象引用来定位目标对象。ORB检查对象引用的时候会检查目标对象是否是远程的。如果对象时本地的ORB进行进程内调用IPC，否则ORB封送参数并且把调用通过网络路由到远程ORB。远程ORB然后在本地调用方法，通过网络把结果发送回客户端。CORBA有语言无关的接口定义语言IDL，各种语言都可以支持CORBA映射。Java IDL支持从Java对象到CORBA IDL对象的映射，各种ORB提供各种语言的CORBA语言绑定，包括C, C++, Java, Python, Lisp, Perl, 和Scheme。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;在Java中最无缝方式进行跨语言交互的方式是直接把Java编译成字节码。Jython脚本语言是Python编程语言整合到Java平台的一个版本。如下例子演示了Jython如何创建一个Java的随机数类型（java.util.Random）并且和这个类型的实例进行交互。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;C:\jython&amp;gt;jython&lt;br/&gt;Jython 2.0 on java1.2.1&lt;br/&gt;Type &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br/&gt;&amp;gt;&amp;gt;&amp;gt; from java.util import Random&lt;br/&gt;&amp;gt;&amp;gt;&amp;gt; r = Random()&lt;br/&gt;&amp;gt;&amp;gt;&amp;gt; r.nextInt()&lt;br/&gt;-790940041&lt;br/&gt;&amp;gt;&amp;gt;&amp;gt; for i in range(5):&lt;br/&gt;...     print r.nextDouble()&lt;br/&gt;...&lt;br/&gt;0.23347681506123852&lt;br/&gt;0.8526595592189546&lt;br/&gt;0.3647833839988137&lt;br/&gt;0.3384865260567278&lt;br/&gt;0.5514469740469587&lt;br/&gt;&amp;gt;&amp;gt;&amp;gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;C#和.NET运行时本来的一个设计目标就是无缝的跨语言交互。任何.NET公共语言运行时的语言都可以基于公共类型系统CTS互相交互。公共类型系统定义了类型如何声明，确保各种语言可以共享类型信息。元数据是描述程序集、类型和应用程序定义的特性的二进制信息，它保存在CLR PE中，或者在程序集加载后保存在内存中。当前.NET运行时支持的语言包括APL, C#, C++, COBOL, Component Pascal, Eiffel, Haskel#/Mondrian, Java, Mercury, Oberon, Perl, Python, Scheme, Smalltalk, ML, 和Visual Basic。由于一种语言中具有的特性很可能在另外一种语言中没有，.NET框架提供了CLS描述一组基本的语言特性和定义如何使用这些特性的规则。CLS规则是公共类型系统的子集，并且通过定义一组编程语言最常见的特性集合来确保跨语言互操作。C#编译器是CLS兼容的编译器，也就是说可以用于编译符合CLS的代码。C#编译器可以检查CLS规范并且在代码使用了不符合CLS功能的时候给出错误。要让C#编译器检查CLS规范可以使用&lt;code&gt;[CLSCompliantAttribute(true)]特性。C#支持的另一种跨语言交互是基于COM的对象，这个机制允许开发者在C#中使用COM，反之亦然。在创建了包装类后，C#对象可以使用COM对象，包装类可以当做普通的C#对象来使用，.NET运行时会处理复杂的参数封送操作。可以使用tlbimp工具来自动创建包装类。对于COM对象使用C#对象，必须创建描述C#对象的类型库，可以使用tlbexp创建类型库以COM的形式来描述C#对象。还可以使用regasm工具来注册程序集。COM对象和C#对象交互的时候，运行时会负责COM和.NET之间数据的封送。C#程序还可以使用extern关键字和DllImport特性来使用任何DLL的功能，这么做的优势是不需要针对C#的调用为方法作特殊处理，并且也不需要有包装来调用既有的代码。&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第四部分：C#有但Java没有的地方&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;1、对象清理&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;为了提供完全控制类使用的资源，C#提供了System.IDisposable接口，它包含Dispose()方法可以让类的使用者在使用类之后释放必要的资源。管理诸如数据库或文件句柄的类可以从这种模式中收益。Dispose提供了一种确定的方式在类不使用的时候释放资源，这和Java或C#的终结器不同。一般会在Dispose方法的实现中调用GC类的SupressFinalize 方法，因为我们一般通过Dispose方法显式释放资源而不需要运行时的终结器。C#还提供了诸如using关键字之类的语法糖通过Dispose方法释放资源。如果类是Disposable的话，最好让Dispose()方法是幂等的（也就是可以多次调用Dispose()），可以在Dispose()方法中设置一个标志位来检查是否已经Dispose。如下例子演示了类保持打开文件，直到Dispose()方法调用后来表示文件不需要打开了。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyClass : IDisposable {     &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;bool&lt;/span&gt; disposed = &lt;span class="kwrd"&gt;false&lt;/span&gt;; &lt;br/&gt;    FileStream f; &lt;br/&gt;    StreamWriter sw; &lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; String name;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; numShowNameCalls = 0; &lt;br/&gt;&lt;br/&gt;    MyClass(&lt;span class="kwrd"&gt;string&lt;/span&gt; name){&lt;br/&gt;             &lt;br/&gt;        &lt;br/&gt;    f = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileStream(&lt;span class="str"&gt;&amp;quot;logfile.txt&amp;quot;&lt;/span&gt;, FileMode.OpenOrCreate); &lt;br/&gt;    sw = &lt;span class="kwrd"&gt;new&lt;/span&gt; StreamWriter(f);&lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.name = name;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Created &amp;quot;&lt;/span&gt; + name);   &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    ~MyClass(){&lt;br/&gt;&lt;br/&gt;    Dispose(&lt;span class="kwrd"&gt;false&lt;/span&gt;); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Dispose(){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(!disposed){&lt;br/&gt;        Dispose(&lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Dispose(&lt;span class="kwrd"&gt;bool&lt;/span&gt; disposing){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;lock&lt;/span&gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt;){ &lt;span class="rem"&gt;/* prevents multiple threads from disposing simultaneously */&lt;/span&gt; &lt;br/&gt;        &lt;br/&gt;        &lt;span class="rem"&gt;/* disposing variable is used to indicate if this method was called from a &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;         * Dispose() call or during finalization. Since finalization order is not &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;         * deterministic, the StreamWriter may be finalized before this object in &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;         * which case, calling Close() on it would be inappropriate so we try to &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;         * avoid that. &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;         */&lt;/span&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;(disposing){     &lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Finalizing &amp;quot;&lt;/span&gt; + name);      &lt;br/&gt;        sw.Close(); &lt;span class="rem"&gt;/* close file since object is done with */&lt;/span&gt; &lt;br/&gt;        GC.SuppressFinalize(&lt;span class="kwrd"&gt;this&lt;/span&gt;);&lt;br/&gt;        disposed = &lt;span class="kwrd"&gt;true&lt;/span&gt;; &lt;br/&gt;        }&lt;br/&gt;        &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;    &lt;br/&gt;   &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ShowName(){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(disposed)            &lt;br/&gt;           &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ObjectDisposedException(&lt;span class="str"&gt;&amp;quot;MyClass&amp;quot;&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    numShowNameCalls++; &lt;br/&gt;    sw.Write(&lt;span class="str"&gt;&amp;quot;ShowName() Call #&amp;quot;&lt;/span&gt; + numShowNameCalls.ToString() + &lt;span class="str"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;);         &lt;br/&gt;    &lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;I am &amp;quot;&lt;/span&gt; + name; &lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;    &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; (MyClass mc = &lt;span class="kwrd"&gt;new&lt;/span&gt; MyClass(&lt;span class="str"&gt;&amp;quot;A MyClass Object&amp;quot;&lt;/span&gt;)){&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 10; i++){&lt;br/&gt;      &lt;br/&gt;        Console.WriteLine(mc.ShowName()); &lt;br/&gt;      &lt;br/&gt;        } &lt;span class="rem"&gt;//for&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    }&lt;span class="rem"&gt;/* runtime calls Dispose on MyClass object once &amp;quot;using&amp;quot; code block is exited, even if exception thrown  */&lt;/span&gt; &lt;br/&gt;    &lt;br/&gt;    }&lt;span class="rem"&gt;//Main &lt;/span&gt;&lt;br/&gt;&lt;br/&gt;}&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;如上的模式和C++方式的析构器很像，只不过不需要考虑内存分配。终结器这种不精确的特性一致被Java开发者诟病，有了Dispose后这不再是问题了。&lt;/p&gt;&lt;p&gt;&lt;em&gt;注意：调用Dispose()方法不等同于要求对象被垃圾回收，只不过由于不需要终结器之后可以加速被回收。&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;2、委托&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;委托是提供回调函数的机制，委托和C或C++的函数指针相似。委托的一个用途就是根据算法使用的类型传入操作到泛型算法。另一个用途就是为事件注册处理程序。在Java中要使用C#委托中相同的功能，可以创建接口然后指定回调方法，比如Comparable接口，的缺点是方法只能是实例方法，其实一般是当做静态方法来使用的。&lt;/p&gt;&lt;p&gt;要使用委托，首先声明和要调用的回调方法返回值和相同参数的委托。然后定义接收以委托作为参数的方法。完成后，使用符合委托的方法来初始化委托的实例，然后把委托传入接收委托作为参数的方法。委托可以接受静态方法和实例方法，甚至同一时刻接收两种，因为委托是多播的。如下演示了创建和使用实例委托的例子。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;&lt;span class="rem"&gt;/* Mammal class hierarchy used to show return type covariance */&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Mammal {&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Mammal(){;}&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Speak(){;} &lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Cat : Mammal{&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Cat(){;}&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Speak(){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Meow&amp;quot;&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Dog : Mammal{&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Dog(){;}&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Speak(){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Woof&amp;quot;&lt;/span&gt;);&lt;br/&gt;    } &lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test {&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;// delegate declaration, similar to a function pointer declaration&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; Mammal CallbackFunction(Dog d);  &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Cat BarkAndScareCat(Dog d) &lt;br/&gt;    {&lt;br/&gt;    d.Speak(); &lt;br/&gt;    Cat c = &lt;span class="kwrd"&gt;new&lt;/span&gt; Cat();&lt;br/&gt;    c.Speak(); &lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; c; &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Mammal BarkAndReturnHome(Dog d) &lt;br/&gt;    {&lt;br/&gt;    d.Speak(); &lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; d; &lt;br/&gt;    }&lt;br/&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;    &lt;br/&gt;    Dog dog            = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dog(); &lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//create delegate using delegate object (old way)&lt;/span&gt;&lt;br/&gt;    CallbackFunction myCallback = &lt;span class="kwrd"&gt;new&lt;/span&gt; CallbackFunction(BarkAndReturnHome); &lt;br/&gt;    myCallback(dog);&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//create delegate using delegate inference (new way) &lt;/span&gt;&lt;br/&gt;    CallbackFunction myCallback2 = BarkAndScareCat;&lt;br/&gt;    myCallback2(dog);&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;} &lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;委托可以作为参数传入方法，和C或C++的函数指针有点相似：&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;&lt;span class="rem"&gt;//delegate base&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; HasDelegates&lt;br/&gt;{&lt;br/&gt;       &lt;br/&gt;    &lt;span class="rem"&gt;// delegate declaration, similar to a function pointer declaration&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; CallbackFunction(&lt;span class="kwrd"&gt;string&lt;/span&gt; a, &lt;span class="kwrd"&gt;int&lt;/span&gt; b);&lt;br/&gt;        &lt;br/&gt;    &lt;span class="rem"&gt;//method that uses the delegate &lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; execCallback(CallbackFunction doCallback, &lt;span class="kwrd"&gt;string&lt;/span&gt; x, &lt;span class="kwrd"&gt;int&lt;/span&gt; y)&lt;br/&gt;    {   &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Executing Callback function...&amp;quot;&lt;/span&gt;);&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; doCallback(x, y);                    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; FunctionDelegates&lt;br/&gt;{&lt;br/&gt;   &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; HasDelegates.CallbackFunction BarFuncCallback = &lt;br/&gt;        &lt;span class="kwrd"&gt;new&lt;/span&gt; HasDelegates.CallbackFunction(FunctionBar); &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; FunctionBar(&lt;span class="kwrd"&gt;string&lt;/span&gt; a, &lt;span class="kwrd"&gt;int&lt;/span&gt; b)&lt;br/&gt;    {   &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Bar: {0} {1}&amp;quot;&lt;/span&gt;, b, a);&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DelegateTest {&lt;br/&gt;&lt;br/&gt;  &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;    &lt;br/&gt;    HasDelegates MyDel = &lt;span class="kwrd"&gt;new&lt;/span&gt; HasDelegates();&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;// with static delegate, no need to know how to create delegate&lt;/span&gt;&lt;br/&gt;    MyDel.execCallback(FunctionDelegates.BarFuncCallback, &lt;span class="str"&gt;&amp;quot;Thirty Three&amp;quot;&lt;/span&gt;, 33);&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;} &lt;span class="rem"&gt;// DelegateTest&lt;/span&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;3、值类型（结构）&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;在Java和C#中，堆上的东西只能等垃圾回收来收集而在栈上的对象会自动被系统回收。一般在栈上分配的内存会比在堆上略快。&lt;/p&gt;&lt;p&gt;在Java中，所有的类都在堆上创建而基元类型在栈上创建。如果对象很小并且很常用的话只能在堆上分配的话会造成一定的性能负担，C#提供了一种机制可以让某种类是基于栈分配的，叫做结构，其实C#内建的诸如int的基元类型就是使用结构来分配的。和类不同，值类型一般按值传递并且不会被垃圾收集。要使用基于栈的类，可以使用struct来替代class关键字。要创建C#结构可以使用和类一样的new关键字。如果结构使用默认构造方法语法创建，那么结构的字段都会使用0初始化。但是，不可以为结构定义默认构造方法。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;struct&lt;/span&gt; Point {&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; x; &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; y; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Point( &lt;span class="kwrd"&gt;int&lt;/span&gt; x, &lt;span class="kwrd"&gt;int&lt;/span&gt; y){&lt;br/&gt;  &lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.x = x; &lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.y = y;&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;  &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ToString(){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; String.Format(&lt;span class="str"&gt;&amp;quot;({0}, {1})&amp;quot;&lt;/span&gt;, x, y); &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    Point start = &lt;span class="kwrd"&gt;new&lt;/span&gt; Point(5, 9); &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Start: &amp;quot;&lt;/span&gt; + start);&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* The line below wouldn't compile if Point was a class */&lt;/span&gt; &lt;br/&gt;    Point end = &lt;span class="kwrd"&gt;new&lt;/span&gt; Point(); &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;End: &amp;quot;&lt;/span&gt; + end);&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;} &lt;span class="rem"&gt;// Point&lt;/span&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;4、运行时类型标识（as运算符）&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;C#的as运算符和C++的dynamic_cast结构一样。as运算符的作用是尝试把类型转换为某种类型，如果不成功的话返回null。&lt;/p&gt;C# Code&lt;br/&gt;MyClass mc = o &lt;span class="kwrd"&gt;as&lt;/span&gt; MyClass; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt;(mc !=  &lt;span class="kwrd"&gt;null&lt;/span&gt;)      &lt;span class="rem"&gt;//check if cast successful &lt;/span&gt;&lt;br/&gt;   mc.doStuff(); &lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;em&gt;注意：as不能用于值类型。&lt;/em&gt; &lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;5、属性&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;属性可以避免直接访问类的成员和Java的getters以及setters很像。可以使用属性来访问类的字段或成员属性，但又避免使用方法。可以创建只读、只写或读写属性，此外还可以创建属性让getter和setter具有不同的访问性（比如public的getter和private的setter），如下是使用属性的例子：&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; User {&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; User(&lt;span class="kwrd"&gt;string&lt;/span&gt; name){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.name = name;   &lt;br/&gt;&lt;br/&gt;    }   &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; name; &lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//property with public getter and private setter&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name{&lt;br/&gt;&lt;br/&gt;    get{&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; name; &lt;br/&gt;    }   &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; set { &lt;br/&gt;        name = &lt;span class="kwrd"&gt;value&lt;/span&gt;; &lt;br/&gt;    }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; minimum_age = 13;   &lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//read-write property for class member, minimum_age&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; MinimumAge{&lt;br/&gt;      &lt;br/&gt;      get{&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; minimum_age; &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    set{&lt;br/&gt;      &lt;br/&gt;      &lt;span class="kwrd"&gt;if&lt;/span&gt;(&lt;span class="kwrd"&gt;value&lt;/span&gt; &amp;gt; 0 &amp;amp;&amp;amp; &lt;span class="kwrd"&gt;value&lt;/span&gt; &amp;lt; 100)&lt;br/&gt;        minimum_age = &lt;span class="kwrd"&gt;value&lt;/span&gt;; &lt;br/&gt;      &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;&amp;quot;{0} is an invalid age, so minimum age remains at {1}&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;value&lt;/span&gt;, minimum_age);&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;  &lt;br/&gt;    User newuser = &lt;span class="kwrd"&gt;new&lt;/span&gt; User(&lt;span class="str"&gt;&amp;quot;Bob Hope&amp;quot;&lt;/span&gt;); &lt;br/&gt;&lt;br/&gt;    User.MinimumAge = -5; &lt;span class="rem"&gt;/* prints error to screen since value invalid */&lt;/span&gt; &lt;br/&gt;    User.MinimumAge = 18; &lt;br/&gt;    &lt;span class="rem"&gt;//newuser.Name = &amp;quot;Kevin Nash&amp;quot;; Causes compiler error since Name property is read-only &lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Minimum Age: &amp;quot;&lt;/span&gt; + User.MinimumAge);       &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Name: {0}&amp;quot;&lt;/span&gt;, newuser.Name);&lt;br/&gt;    }&lt;br/&gt;} &lt;span class="rem"&gt;// User&lt;/span&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;6、多维度数组&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;如下代码演示了多维数组和交错数组的区别&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ArrayTest {&lt;br/&gt;&lt;br/&gt;  &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt;[,] multi = { {0, 1}, {2, 3}, {4, 5}, {6, 7} };  &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i=0, size = multi.GetLength(0); i &amp;lt; size; i++){&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; j=0, size2 = multi.GetLength(1); j &amp;lt; size2; j++){&lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;&amp;quot;multi[&amp;quot;&lt;/span&gt; + i + &lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt; + j + &lt;span class="str"&gt;&amp;quot;] = &amp;quot;&lt;/span&gt; + multi[i,j]);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt;[][] jagged = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[4][];&lt;br/&gt;    jagged[0] = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[2]{0, 1};&lt;br/&gt;    jagged[1] = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[2]{2, 3};&lt;br/&gt;    jagged[2] = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[2]{4, 5};&lt;br/&gt;    jagged[3] = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[2]{6, 7};&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i=0, size = jagged.Length; i &amp;lt; size; i++){&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; j=0, size2 = jagged[1].Length; j &amp;lt; size2; j++){&lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;&amp;quot;jagged[&amp;quot;&lt;/span&gt; + i + &lt;span class="str"&gt;&amp;quot;][&amp;quot;&lt;/span&gt; + j + &lt;span class="str"&gt;&amp;quot;] = &amp;quot;&lt;/span&gt; + jagged[i][j]);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;} &lt;span class="rem"&gt;// ArrayTest&lt;/span&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;7、索引器&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;索引器是重写类[]运算符的语法。如果类包含另外一种对象的话，索引器就很有用。索引器的灵活之处在于支持任何类型，比如整数或字符串、还可以创建索引器允许多维数组语法，可以在索引器中混合和匹配不同的类型，最后，索引器可以重载。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; IndexerTest: IEnumerable, IEnumerator {&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; Hashtable list; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; IndexerTest (){&lt;br/&gt;&lt;br/&gt;    index = -1; &lt;br/&gt;    list = &lt;span class="kwrd"&gt;new&lt;/span&gt; Hashtable();     &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//indexer that indexes by number&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;[&lt;span class="kwrd"&gt;int&lt;/span&gt; column]{&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    get{&lt;br/&gt;    &lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; list[column];&lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    set{&lt;br/&gt;      &lt;br/&gt;        list[column] = &lt;span class="kwrd"&gt;value&lt;/span&gt;; &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* indexer that indexes by name */&lt;/span&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;[&lt;span class="kwrd"&gt;string&lt;/span&gt; name]{&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    get{&lt;br/&gt;    &lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;[ConvertToInt(name)];&lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    set{&lt;br/&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;[ConvertToInt(name)] = &lt;span class="kwrd"&gt;value&lt;/span&gt;; &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* Convert strings to integer equivalents */&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; ConvertToInt(&lt;span class="kwrd"&gt;string&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; loVal = &lt;span class="kwrd"&gt;value&lt;/span&gt;.ToLower(); &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;switch&lt;/span&gt;(loVal){&lt;br/&gt;        &lt;br/&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;zero&amp;quot;&lt;/span&gt;: &lt;span class="kwrd"&gt;return&lt;/span&gt; 0;&lt;br/&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;one&amp;quot;&lt;/span&gt;: &lt;span class="kwrd"&gt;return&lt;/span&gt; 1;&lt;br/&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;two&amp;quot;&lt;/span&gt;: &lt;span class="kwrd"&gt;return&lt;/span&gt; 2;&lt;br/&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;three&amp;quot;&lt;/span&gt;:  &lt;span class="kwrd"&gt;return&lt;/span&gt; 3;&lt;br/&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;four&amp;quot;&lt;/span&gt;: &lt;span class="kwrd"&gt;return&lt;/span&gt; 4;&lt;br/&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;five&amp;quot;&lt;/span&gt;: &lt;span class="kwrd"&gt;return&lt;/span&gt; 5; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;default&lt;/span&gt;:&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; 0; &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; 0; &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/** &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;     * Needed to implement IEnumerable interface. &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;     */&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; IEnumerator GetEnumerator(){ &lt;span class="kwrd"&gt;return&lt;/span&gt; (IEnumerator) &lt;span class="kwrd"&gt;this&lt;/span&gt;; }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/** &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;     * Needed for IEnumerator. &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;     */&lt;/span&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; index; &lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/** &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;     * Needed for IEnumerator. &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;     */&lt;/span&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; MoveNext(){&lt;br/&gt;&lt;br/&gt;    index++;&lt;br/&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(index &amp;gt;= list.Count)&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;; &lt;br/&gt;    &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;; &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/** &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;     * Needed for IEnumerator. &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;     */&lt;/span&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Reset(){&lt;br/&gt;    index = -1; &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/** &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;     * Needed for IEnumerator. &lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;     */&lt;/span&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Current{&lt;br/&gt;&lt;br/&gt;    get{&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; list[index];&lt;br/&gt;    }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    IndexerTest it = &lt;span class="kwrd"&gt;new&lt;/span&gt; IndexerTest(); &lt;br/&gt;    it[0] = &lt;span class="str"&gt;&amp;quot;A&amp;quot;&lt;/span&gt;; &lt;br/&gt;    it[1] = &lt;span class="str"&gt;&amp;quot;B&amp;quot;&lt;/span&gt;;&lt;br/&gt;    it[2] = &lt;span class="str"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;;&lt;br/&gt;    it[3] = &lt;span class="str"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;; &lt;br/&gt;    it[4] = &lt;span class="str"&gt;&amp;quot;E&amp;quot;&lt;/span&gt;;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Integer Indexing: it[0] = &amp;quot;&lt;/span&gt; + it[0]);    &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;String  Indexing: it[\&amp;quot;Three\&amp;quot;] = &amp;quot;&lt;/span&gt; + it[&lt;span class="str"&gt;&amp;quot;Three&amp;quot;&lt;/span&gt;]);&lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Printing entire contents of object via enumerating through indexer :&amp;quot;&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt;( &lt;span class="kwrd"&gt;string&lt;/span&gt; str &lt;span class="kwrd"&gt;in&lt;/span&gt; it){&lt;br/&gt;        Console.WriteLine(str);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;} &lt;span class="rem"&gt;// IndexerTest&lt;/span&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;8、预处理指令&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;C#包含预处理器，相当于C/C++预处理器的有限子集。C#预处理器没有#include文件的能力也没有使用#define进行文本替换的能力。主要的能力在于使用#define和#undef标识符以及通过#if和#elif以及#else选择编译某段代码的能力。#error和#warning指示器可以在编译的时候让指示器之后的错误或警告消息显示出来。#pragma指示器用于处理屏蔽编译器警告消息。最后，#line指示器可以用于编译器发现错误的时候指定源文件行号。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="preproc"&gt;#define&lt;/span&gt; DEBUG &lt;span class="rem"&gt;/* #define must be first token in file */&lt;/span&gt; &lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;&lt;span class="preproc"&gt;#pragma&lt;/span&gt; warning disable 169 &lt;span class="rem"&gt;/* Disable 'field never used' warning */&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; PreprocessorTest{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; unused_field; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;    &lt;br/&gt;    &lt;span class="preproc"&gt;#if&lt;/span&gt; DEBUG&lt;br/&gt;      Console.WriteLine(&lt;span class="str"&gt;&amp;quot;DEBUG Mode := On&amp;quot;&lt;/span&gt;);&lt;br/&gt;    &lt;span class="preproc"&gt;#else&lt;/span&gt;&lt;br/&gt;      Console.WriteLine(&lt;span class="str"&gt;&amp;quot;DEBUG Mode := Off&amp;quot;&lt;/span&gt;);&lt;br/&gt;    &lt;span class="preproc"&gt;#endif&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;9、别名&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;using关键字可以用于为完全限定名设置别名，和C/C++的typedef相似。如果类的完全限定名需要解决命名空间冲突的话，这就很有用了。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Terminal = System.Console; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;       Terminal.WriteLine(&lt;span class="str"&gt;&amp;quot;Terminal.WriteLine is equivalent to System.Console.Writeline&amp;quot;&lt;/span&gt;); &lt;br/&gt;&lt;br/&gt;     }&lt;br/&gt;&lt;br/&gt;}&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;10、运行时代码生成&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Reflection.Emit命名空间包含了一些类可以用于生成.NET中间语言，以及在运行时在内存中构建类甚至把PE文件写到磁盘上。这类似Java的那些通过生成Java字节码写入磁盘，用于在运行时创建Java类然后被程序使用的类库。Reflection.Enmit命名空间主要的用户是编译器或脚本引擎的作者。比如，System.Text.RegularExpressions使用Reflection.Emit类库来为每一个编译后的表达式生成自定义匹配引擎。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;11、指针和不安全的代码&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;尽管C#和Java一样，不能使用指针类型，但是如果C#代码在unsafe上下文中执行的话就可以使用指针类型。如果C#代码在unsafe上下文中执行，那么就会禁止许多运行时检查，程序也必须在所运行的机器上有完全信任权限。写unsafe代码的语法和语义和在C和C++中使用指针的语法和语义相似。写unsafe代码时，必须使用unsafe关键字把代码块指定为unsafe的，并且程序必须使用/unsafe编译器开关编译。由于垃圾回收期可能会在程序执行的过程中重新分配托管变量，所以在fixed代码块中使用托管变量的时候需要使用fixed关键字来固定变量地址。如果没有fixed关键字的话，标记和压缩垃圾回收期可能会在回收的过程中移动变量的地址。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; UnsafeTest{&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;unsafe&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Swap(&lt;span class="kwrd"&gt;int&lt;/span&gt;* a, &lt;span class="kwrd"&gt;int&lt;/span&gt;*b){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; temp = *a; &lt;br/&gt;    *a = *b; &lt;br/&gt;    *b = temp; &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;unsafe&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Sort(&lt;span class="kwrd"&gt;int&lt;/span&gt;* array, &lt;span class="kwrd"&gt;int&lt;/span&gt; size){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i= 0; i &amp;lt; size - 1; i++)&lt;br/&gt;        &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; j = i + 1; j &amp;lt; size; j++)&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;(array[i] &amp;gt; array[j])&lt;br/&gt;            Swap(&amp;amp;array[i], &amp;amp;array[j]); &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;unsafe&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt;[] array = {9, 1, 3, 6, 11, 99, 37, 17, 0, 12}; &lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Unsorted Array:&amp;quot;&lt;/span&gt;); &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; x &lt;span class="kwrd"&gt;in&lt;/span&gt; array)&lt;br/&gt;        Console.Write(x + &lt;span class="str"&gt;&amp;quot; &amp;quot;&lt;/span&gt;); &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;fixed&lt;/span&gt;( &lt;span class="kwrd"&gt;int&lt;/span&gt;* iptr = array ){  &lt;span class="rem"&gt;// must use fixed to get address of array&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;        Sort(iptr, array.Length);&lt;br/&gt;        &lt;br/&gt;    }&lt;span class="rem"&gt;//fixed &lt;/span&gt;&lt;br/&gt;    &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\nSorted Array:&amp;quot;&lt;/span&gt;); &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; x &lt;span class="kwrd"&gt;in&lt;/span&gt; array)&lt;br/&gt;        Console.Write(x + &lt;span class="str"&gt;&amp;quot; &amp;quot;&lt;/span&gt;); &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;12、按引用传递&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;在Java中，传给方法的参数是按值传递的，方法操作的是复制的数据而不是原来的数据。在C#中，可以指定参数按照引用传递而不是数据拷贝。有的时候如果希望方法返回超过一个对象的时候就有用。指定参数按引用传递的关键字是ref和out。区别是使用ref的话传入参数必须初始化，而out则不需要。&lt;/p&gt;Java Code&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; PassByRefTest{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; changeMe(String s){&lt;br/&gt;&lt;br/&gt;    s = &lt;span class="str"&gt;&amp;quot;Changed&amp;quot;&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; swap(&lt;span class="kwrd"&gt;int&lt;/span&gt; x, &lt;span class="kwrd"&gt;int&lt;/span&gt; y){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; z = x;&lt;br/&gt;    x = y;&lt;br/&gt;    y = z;&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; a = 5, b = 10; &lt;br/&gt;    String s = &lt;span class="str"&gt;&amp;quot;Unchanged&amp;quot;&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;    swap(a, b); &lt;br/&gt;    changeMe(s); &lt;br/&gt;&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;&amp;quot;a := &amp;quot;&lt;/span&gt; + a + &lt;span class="str"&gt;&amp;quot;, b := &amp;quot;&lt;/span&gt; + b + &lt;span class="str"&gt;&amp;quot;, s = &amp;quot;&lt;/span&gt; + s);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;OUTPUT&lt;br/&gt;a := 5, b := 10, s = Unchanged&lt;br/&gt;&lt;br/&gt;C# Code&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; PassByRefTest{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ChangeMe(&lt;span class="kwrd"&gt;out&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; s){&lt;br/&gt;&lt;br/&gt;    s = &lt;span class="str"&gt;&amp;quot;Changed&amp;quot;&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Swap(&lt;span class="kwrd"&gt;ref&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; x, &lt;span class="kwrd"&gt;ref&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; y){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; z = x;&lt;br/&gt;    x = y;&lt;br/&gt;    y = z;&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; a = 5, b = 10; &lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; s; &lt;br/&gt;&lt;br/&gt;    Swap(&lt;span class="kwrd"&gt;ref&lt;/span&gt; a, &lt;span class="kwrd"&gt;ref&lt;/span&gt; b); &lt;br/&gt;    ChangeMe(&lt;span class="kwrd"&gt;out&lt;/span&gt; s); &lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;a := &amp;quot;&lt;/span&gt; + a + &lt;span class="str"&gt;&amp;quot;, b := &amp;quot;&lt;/span&gt; + b + &lt;span class="str"&gt;&amp;quot;, s = &amp;quot;&lt;/span&gt; + s);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;OUTPUT&lt;br/&gt;a := 10, b := 5, s = Changed&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;13、逐字字符串&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;C#提供了一种方式来避免在字符串常量中使用转移序列。唯一的例外是双引号需要使用两个双引号，可以在字符串声明的时候使用@来声明逐字字符串。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; VerbatimTest{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(){&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//verbatim string &lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; filename  = &lt;span class="str"&gt;@&amp;quot;C:\My Documents\My Files\File.html&amp;quot;&lt;/span&gt;; &lt;br/&gt;    &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Filename 1: &amp;quot;&lt;/span&gt; + filename);&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//regular string &lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; filename2 =  &lt;span class="str"&gt;&amp;quot;C:\\My Documents\\My Files\\File.html&amp;quot;&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Filename 2: &amp;quot;&lt;/span&gt; + filename2);&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; snl_celebrity_jeopardy_skit = &lt;span class="str"&gt;@&amp;quot;&lt;br/&gt;        Darrell Hammond (Sean Connery) : I'll take &amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;Swords&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot; for $400&lt;br/&gt;        Will Farrell    (Alex Trebek)  : That's S-Words, Mr Connery.&lt;br/&gt;        &amp;quot;&lt;/span&gt;;&lt;br/&gt;&lt;br/&gt;    Console.WriteLine(snl_celebrity_jeopardy_skit);&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;14、溢出检查&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;C#提供了显式检测或忽略溢出条件的选项。溢出条件检测到之后会抛出System.OverflowException。由于溢出检查会带来性能损失，所以需要通过/checked+编译选项显式启用。可以通过在代码块声明checked来表示代码总是进行溢出检查，或是使用unchecked表示总是取消溢出检查。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; CheckedTest{&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; num = 5000; &lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* OVERFLOW I */&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;byte&lt;/span&gt; a  = (&lt;span class="kwrd"&gt;byte&lt;/span&gt;) num; &lt;span class="rem"&gt;/* overflow detected only if /checked compiler option on */&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* OVERFLOW II */&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;checked&lt;/span&gt;{&lt;br/&gt;                &lt;br/&gt;        &lt;span class="kwrd"&gt;byte&lt;/span&gt; b = (&lt;span class="kwrd"&gt;byte&lt;/span&gt;) num; &lt;span class="rem"&gt;/* overflow ALWAYS detected */&lt;/span&gt;     &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* OVERFLOW III */&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;unchecked&lt;/span&gt;{&lt;br/&gt;                &lt;br/&gt;        &lt;span class="kwrd"&gt;byte&lt;/span&gt; c = (&lt;span class="kwrd"&gt;byte&lt;/span&gt;) num; &lt;span class="rem"&gt;/* overflow NEVER detected */&lt;/span&gt;      &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    }&lt;span class="rem"&gt;//Main&lt;/span&gt;&lt;br/&gt;}&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;15、显式接口实现&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;有的时候在实现接口的时候可能会遇到冲突，比如FileRepresentation类可能会实现IWindow和IFileHandler接口，他妈两个接口都有Close方法，IWindow的Close方法表示关闭GUI窗口，而IFileHandler 的Close方法表示关闭文件。在Java中除了只写一个Close方法之外别无他法，而在C#中可以为每一个接口写一个实现。比如对于之前提到的例子，FileRepresentation类可以有两个不同的Close方法。注意，显式接口方法是private的，并且只有转换成相应类型之后才能进行方法调用。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;interface&lt;/span&gt; IVehicle{&lt;br/&gt;    &lt;br/&gt;    &lt;span class="rem"&gt;//identify vehicle by model, make, year&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; IdentifySelf();    &lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;interface&lt;/span&gt; IRobot{&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//identify robot by name&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; IdentifySelf();&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; TransformingRobot : IRobot, IVehicle{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; model; &lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; make;&lt;br/&gt;    &lt;span class="kwrd"&gt;short&lt;/span&gt;  year; &lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; name;&lt;br/&gt;    &lt;br/&gt;&lt;br/&gt;    TransformingRobot(String name, String model, String make, &lt;span class="kwrd"&gt;short&lt;/span&gt; year){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.name  = name;&lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.model = model; &lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.make  = make; &lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.year  = year; &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; IRobot.IdentifySelf(){&lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;My name is &amp;quot;&lt;/span&gt; + &lt;span class="kwrd"&gt;this&lt;/span&gt;.name);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; IVehicle.IdentifySelf(){&lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Model:&amp;quot;&lt;/span&gt; + &lt;span class="kwrd"&gt;this&lt;/span&gt;.model + &lt;span class="str"&gt;&amp;quot; Make:&amp;quot;&lt;/span&gt; + &lt;span class="kwrd"&gt;this&lt;/span&gt;.make + &lt;span class="str"&gt;&amp;quot; Year:&amp;quot;&lt;/span&gt; + &lt;span class="kwrd"&gt;this&lt;/span&gt;.year);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(){&lt;br/&gt;&lt;br/&gt;    TransformingRobot tr = &lt;span class="kwrd"&gt;new&lt;/span&gt; TransformingRobot(&lt;span class="str"&gt;&amp;quot;SedanBot&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Toyota&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Corolla&amp;quot;&lt;/span&gt;, 2001); &lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;// tr.IdentifySelf(); ERROR &lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    IVehicle v = (IVehicle) tr; &lt;br/&gt;&lt;br/&gt;    IRobot r   = (IRobot) tr; &lt;br/&gt;&lt;br/&gt;    v.IdentifySelf(); &lt;br/&gt;    &lt;br/&gt;    r.IdentifySelf();   &lt;br/&gt;   &lt;br/&gt;   }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;OUTPUT&lt;br/&gt;Model:Toyota Make:Corolla Year:2001&lt;br/&gt;My name &lt;span class="kwrd"&gt;is&lt;/span&gt; SedanBot&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;16、友元程序集&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;友元程序集特性允许内部类型或内部方法被其它程序集访问。可以使用&lt;code&gt;[InternalsVisibleToAttribute]特性来实现友元程序集。如下代码演示了2个源文件编译成2个程序集来使用友元程序集特性。&lt;/code&gt;&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="rem"&gt;// friend_assembly_test.cs&lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;// compile with: /target:library&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Runtime.CompilerServices;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;[assembly:InternalsVisibleTo(&lt;span class="str"&gt;&amp;quot;friend_assembly_test_2&amp;quot;&lt;/span&gt;)]&lt;br/&gt;&lt;br/&gt;&lt;span class="rem"&gt;// internal by default&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Friend &lt;br/&gt;{&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Hello() &lt;br/&gt;    {&lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Hello World!&amp;quot;&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="rem"&gt;// public type with internal member&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Friend2 &lt;br/&gt;{&lt;br/&gt; &lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; secret = &lt;span class="str"&gt;&amp;quot;I like jelly doughnuts&amp;quot;&lt;/span&gt;;  &lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;C# Code 2&lt;br/&gt;&lt;span class="rem"&gt;// friend_assembliy_test_2.cs&lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;// compile with: /reference:friend_assembly_test.dll /out:friend_assembly_test_2.exe&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; FriendFinder &lt;br/&gt;{&lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main() &lt;br/&gt;    {&lt;br/&gt;        &lt;span class="rem"&gt;// access an internal type&lt;/span&gt;&lt;br/&gt;        Friend f = &lt;span class="kwrd"&gt;new&lt;/span&gt; Friend();&lt;br/&gt;        f.Hello();&lt;br/&gt;&lt;br/&gt;        Friend2 f2 = &lt;span class="kwrd"&gt;new&lt;/span&gt; Friend2();&lt;br/&gt;        &lt;span class="rem"&gt;// access an internal member of a public type&lt;/span&gt;&lt;br/&gt;        Console.WriteLine(f2.secret);&lt;br/&gt;    }&lt;br/&gt;}&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;17、命名空间限定符&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;项目越大越有可能发生命名空间冲突。C#有::运算符来指定命名空间的作用域。运算符左边的操作数表示的是解决冲突的作用域，右边的操作数表示的是要解决冲突的名字。左操作数可以是关键字global指代全局作用域或是命名空间的别名。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; sys = System; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; TestLib{&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; System {} &lt;br/&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DateTime Console = DateTime.Now;   &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(){&lt;br/&gt;    &lt;span class="rem"&gt;//Console.WriteLine(&amp;quot;Hello world&amp;quot;); doesn't work due to static member variable named 'Console'&lt;/span&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//System.Console.WriteLine(&amp;quot;Hello world&amp;quot;); doesn't work due to nested class named 'System'&lt;/span&gt;&lt;br/&gt;        &lt;br/&gt;    global::System.Console.WriteLine(&lt;span class="str"&gt;&amp;quot;The time is &amp;quot;&lt;/span&gt; + Console); &lt;br/&gt;&lt;br/&gt;    sys::Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Hello again&amp;quot;&lt;/span&gt;); &lt;br/&gt;    }&lt;br/&gt; }&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;18、迭代器&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;对于支持foreach循环的数据结构，必须实现或返回System.Collections.IEnumerable的实例。枚举器写起来还是有点麻烦的，yield关键字可以把任何方法或属性转换为枚举器。可以使用yield return语句来一个一个返回内容，可以使用yield break来表示结束了序列。方法或属性必须返回IEnumerable, IEnumerable&amp;lt;T&amp;gt;, IEnumerator 或IEnumerator&amp;lt;T&amp;gt;中的一个。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] fruit = {&lt;span class="str"&gt;&amp;quot;banana&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;apple&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;orange&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;pear&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;grape&amp;quot;&lt;/span&gt;};&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] vegetables = {&lt;span class="str"&gt;&amp;quot;lettuce&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;cucumber&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;peas&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;carrots&amp;quot;&lt;/span&gt;};&lt;br/&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IEnumerable FruitAndVeg{&lt;br/&gt; &lt;br/&gt;  get{&lt;br/&gt;   &lt;br/&gt;   &lt;span class="kwrd"&gt;foreach&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt; f &lt;span class="kwrd"&gt;in&lt;/span&gt; fruit){&lt;br/&gt;    &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; f; &lt;br/&gt;   }&lt;br/&gt;&lt;br/&gt;   &lt;span class="kwrd"&gt;foreach&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt; v &lt;span class="kwrd"&gt;in&lt;/span&gt; vegetables){&lt;br/&gt;    &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; v; &lt;br/&gt;   }&lt;br/&gt;&lt;br/&gt;   &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;break&lt;/span&gt;; &lt;span class="rem"&gt;//optional&lt;/span&gt;&lt;br/&gt;  }&lt;br/&gt; &lt;br/&gt; }&lt;br/&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(){&lt;br/&gt; &lt;br/&gt;   &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; produce &lt;span class="kwrd"&gt;in&lt;/span&gt; Test.FruitAndVeg){&lt;br/&gt;     Console.WriteLine(produce);&lt;br/&gt;   }&lt;br/&gt; }&lt;br/&gt;&lt;br/&gt;}&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;19、部分类&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;部分类特性使得我们可以在多个源文件中定义单个类、接口或接口。对于自动生成的代码特别有用。在这个特性出现之前，我们可能会修改自动生成的代码，因为手写代码和自动生成的代码位于一个文件中。而有了这个特性，就减少了出现这种情况的可能。可以通过在类声明中使用partial关键字来启动部分类，如下代码演示了定义在两个源文件中的部分类。注意，一个源文件中的方法和属性可以引用另一个源文件中定义的方法和属性。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] fruit = {&lt;span class="str"&gt;&amp;quot;banana&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;apple&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;orange&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;pear&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;grape&amp;quot;&lt;/span&gt;};&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] vegetables = {&lt;span class="str"&gt;&amp;quot;lettuce&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;cucumber&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;peas&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;carrots&amp;quot;&lt;/span&gt;};&lt;br/&gt; &lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(){&lt;br/&gt; &lt;br/&gt;   &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; produce &lt;span class="kwrd"&gt;in&lt;/span&gt; Test.FruitAndVeg){&lt;br/&gt;     Console.WriteLine(produce);&lt;br/&gt;   }&lt;br/&gt; }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;C# Code 2&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IEnumerable FruitAndVeg{&lt;br/&gt; &lt;br/&gt;  get{&lt;br/&gt;   &lt;span class="kwrd"&gt;foreach&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt; f &lt;span class="kwrd"&gt;in&lt;/span&gt; fruit){&lt;br/&gt;    &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; f; &lt;br/&gt;   }&lt;br/&gt;   &lt;span class="kwrd"&gt;foreach&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt; v &lt;span class="kwrd"&gt;in&lt;/span&gt; vegetables){&lt;br/&gt;    &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; v; &lt;br/&gt;   }&lt;br/&gt;  }&lt;br/&gt; &lt;br/&gt; }&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;需要注意的是类上的特性会进行合并，因此矛盾的特性是不允许的，比如一个文件中类声明的是private另一个文件声明的是public的。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;20、可空类型&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;可空类型System.Nullable类型的实例。可空类型可以表示底层值类型的值也可以表示空值。例如，Nullable&amp;lt;bool&amp;gt;可以表示值true、false和null。可空类型的变量可以使用值的类型加上?运算符来声明。bool?等价于Nullable&amp;lt;bool&amp;gt;。每一个可空类型都有HasValue属性来表示是否具有有效的值或是null。可空类型真实的值保存在其Value属性中。GetValueOrDefault()方法可以返回可空类型的值或如果是null的话返回底层值类型的默认值。&lt;/p&gt;&lt;p&gt;可空类型在用于把C#对象映射到关系型数据库的时候很有用，因为在SQL数据库中可以存在null的有效值。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;int&lt;/span&gt;? x = 5; &lt;br/&gt; &lt;br/&gt;  &lt;span class="kwrd"&gt;if&lt;/span&gt;(x.HasValue){&lt;br/&gt;   Console.WriteLine(&lt;span class="str"&gt;&amp;quot;The value of x is &amp;quot;&lt;/span&gt; + x.Value);&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;  x = &lt;span class="kwrd"&gt;null&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;  &lt;span class="rem"&gt;//prints 0 &lt;/span&gt;&lt;br/&gt;  Console.WriteLine(x.GetValueOrDefault());&lt;br/&gt; }&lt;br/&gt;&lt;br/&gt;}&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;??运算符叫做空结合运算符，用于测试可空类型的值，并且在值是空的情况下返回另外一个值。因为x??y等价于x==(nulll ? y : x)。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;int&lt;/span&gt;? x = &lt;span class="kwrd"&gt;null&lt;/span&gt;; &lt;br/&gt;  &lt;span class="kwrd"&gt;int&lt;/span&gt;  y = x ?? 5;&lt;br/&gt;&lt;br/&gt;  &lt;span class="rem"&gt;//prints 5 &lt;/span&gt;&lt;br/&gt;  Console.WriteLine(y);&lt;br/&gt; }&lt;br/&gt;&lt;br/&gt;}&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;21、匿名方法&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;匿名方法是和委托相关的一个特性。匿名方法是用于以匿名形式声明委托的方法，而不需要一个独立的方法。如下代码比较了使用匿名方法和具名方法的委托：&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test {&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;// delegate declaration, similar to a function pointer declaration&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; CallbackFunction(&lt;span class="kwrd"&gt;string&lt;/span&gt; a, &lt;span class="kwrd"&gt;int&lt;/span&gt; b);&lt;br/&gt;  &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PrintString(&lt;span class="kwrd"&gt;string&lt;/span&gt; a, &lt;span class="kwrd"&gt;int&lt;/span&gt; b){&lt;br/&gt;      &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; b ; i++)&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;{0}.) {1}&amp;quot;&lt;/span&gt;, i + 1, a);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;    &lt;br/&gt;    &lt;span class="rem"&gt;/* anonymous code block */&lt;/span&gt;&lt;br/&gt;    CallbackFunction cf = &lt;span class="kwrd"&gt;delegate&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; a, &lt;span class="kwrd"&gt;int&lt;/span&gt; b){ &lt;br/&gt;                             &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; b ; i++)&lt;br/&gt;                               Console.WriteLine(&lt;span class="str"&gt;&amp;quot;{0}.) {1}&amp;quot;&lt;/span&gt;, i + 1, a);&lt;br/&gt;                          };&lt;br/&gt;&lt;br/&gt;    cf(&lt;span class="str"&gt;&amp;quot;Thirty Three&amp;quot;&lt;/span&gt;, 10); &lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* using a named delegate function */&lt;/span&gt;&lt;br/&gt;    CallbackFunction cf2 = &lt;span class="kwrd"&gt;new&lt;/span&gt; CallbackFunction(Test.PrintString); &lt;br/&gt;    cf2(&lt;span class="str"&gt;&amp;quot;Twenty Two&amp;quot;&lt;/span&gt;, 5); &lt;br/&gt;    }&lt;br/&gt;}&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;在使用的时候要记住匿名方法有一些限制，比如诸如break、goto和contiune之类的跳转语句不能用于从匿名方法跳转到外部。匿名方法也不能引用定义在外部方法的ref或out参数。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;（其实还有很多，感叹C#的伟大）&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第五部分：Java有但C#没有的地方&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;1、受检查的异常&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;在异常这个概念出现之前，大多数异常处理都是通过返回代码进行。异常对于返回值来说有很多优势：&lt;/p&gt;&lt;p&gt;1）提供了一致的模型来处理错误和其它非预期的情况&lt;/p&gt;&lt;p&gt;2）如果没有在当前上下文中处理异常的话可以向上传播&lt;/p&gt;&lt;p&gt;3）开发者可以把处理错误的代码和普通业务逻辑分离&lt;/p&gt;&lt;p&gt;Java创建了额外的机制来处理受检查的异常和不受检查的异常。对于受检查的异常，调用的方法必须捕获异常，或通过throws声明异常必须被其调用方法处理。从另外一方面来说，不受检查的异常不需要catch也或用throws子句声明，不受检查的异常和返回代码一样不会让编译器出警告或错误，但是如果在运行时忽略异常的话同样会终止程序。受检查的异常一般用于告诉调用者如何和为什么会发生调用失败。不受检查的异常是一般程序中大部分地方都会发生的异常，如果都要进行显式检查的话开销比价值大。比如空对象引用的异常或是数组越界的异常，如果是收检查的异常话，就需要在每一个访问对象或访问数组的时候都进行try catch，因此比较适合不受检查的异常。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;在C#中所有异常都是未收检查的异常，也没有throws子句。这么做的主要劣势是API只能通过文档来告诉调用者自己会抛出哪些异常。比如对于如下的代码，唯一知道下面方法会出现哪些异常的方法是查看所有调用方法的源代码或这些方法的源代码。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GetMessageFromServer(&lt;span class="kwrd"&gt;string&lt;/span&gt; server) &lt;br/&gt; {&lt;br/&gt;    &lt;span class="rem"&gt;//Set up variables and String to write to the server&lt;/span&gt;&lt;br/&gt;    Encoding ASCII = Encoding.ASCII;&lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; Get = &lt;span class="str"&gt;&amp;quot;GET / HTTP/1.1\r\nHost: &amp;quot;&lt;/span&gt; + server + &lt;br/&gt;                 &lt;span class="str"&gt;&amp;quot;\r\nConnection: Close\r\n\r\n&amp;quot;&lt;/span&gt;;&lt;br/&gt;    Byte[] ByteGet = ASCII.GetBytes(Get);&lt;br/&gt;    Byte[] RecvBytes = &lt;span class="kwrd"&gt;new&lt;/span&gt; Byte[256];&lt;br/&gt;    String strRetPage = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br/&gt; &lt;br/&gt;    &lt;span class="rem"&gt;// IPAddress and IPEndPoint represent the endpoint that will&lt;/span&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//   receive the request&lt;/span&gt;&lt;br/&gt;    &lt;span class="rem"&gt;// Get first IPAddress in list return by DNS&lt;/span&gt;&lt;br/&gt;    IPAddress hostadd = Dns.Resolve(server).AddressList[0];&lt;br/&gt;    IPEndPoint EPhost = &lt;span class="kwrd"&gt;new&lt;/span&gt; IPEndPoint(hostadd, 80);&lt;br/&gt; &lt;br/&gt;    &lt;span class="rem"&gt;//Create the Socket for sending data over TCP&lt;/span&gt;&lt;br/&gt;    Socket s = &lt;span class="kwrd"&gt;new&lt;/span&gt; Socket(AddressFamily.InterNetwork, SocketType.Stream,&lt;br/&gt;       ProtocolType.Tcp );&lt;br/&gt; &lt;br/&gt;    &lt;span class="rem"&gt;// Connect to host using IPEndPoint&lt;/span&gt;&lt;br/&gt;    s.Connect(EPhost);&lt;br/&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (!s.Connected)&lt;br/&gt;    {&lt;br/&gt;       strRetPage = &lt;span class="str"&gt;&amp;quot;Unable to connect to host&amp;quot;&lt;/span&gt;;&lt;br/&gt;       &lt;span class="kwrd"&gt;return&lt;/span&gt; strRetPage;&lt;br/&gt;    }&lt;br/&gt; &lt;br/&gt;    &lt;span class="rem"&gt;// Sent the GET text to the host&lt;/span&gt;&lt;br/&gt;    s.Send(ByteGet, ByteGet.Length, 0);&lt;br/&gt; &lt;br/&gt;    &lt;span class="rem"&gt;// Receive the page, loop until all bytes are received&lt;/span&gt;&lt;br/&gt;    Int32 bytes = s.Receive(RecvBytes, RecvBytes.Length, 0);&lt;br/&gt;    strRetPage = &lt;span class="str"&gt;&amp;quot;Default HTML page on &amp;quot;&lt;/span&gt; + server + &lt;span class="str"&gt;&amp;quot;:\r\n&amp;quot;&lt;/span&gt;;&lt;br/&gt;    strRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, bytes);&lt;br/&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt; (bytes &amp;gt; 0)&lt;br/&gt;    {&lt;br/&gt;       bytes = s.Receive(RecvBytes, RecvBytes.Length, 0);&lt;br/&gt;       strRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, bytes);&lt;br/&gt;    }&lt;br/&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; strRetPage;&lt;br/&gt; }&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;上面的代码取自.NET框架Beta2文档的Socket类。注意到，在这段代码中没有捕获异常。如下是根据文档得出的这个方法可能抛出的异常：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201202/201202101751345713.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201202/201202101751347906.png" width="330" height="164" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;（后面关于有无这个特性好坏的争论就不翻译了）&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;2、跨平台移植&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Java技术一个很大的卖点就是Java写的应用程序一次编写到处运行。Sun官方支持Linux、Solaris 和 Windows，其它一些公司也实现了OS/2, AIX 和MacOS平台的Java。.NET也通过Mono项目和Ximian提供了移植性的支持。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;3、扩展&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Java扩展机制允许开发者扩展核心Java平台。开发者可以创建让Java运行时当做认为是核心Java类的类和包，比如&lt;code&gt;java.lang, java.util, java.net等。&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;code&gt;4、strictfp&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;code&gt;在Java中&lt;code&gt;strictfp是可以用于类、方法或借口声明的修饰符，用于确保符合IEEE 754的精确浮点数算术。当对一个类或接口使用 strictfp 关键字时，该类中的所有代码，包括嵌套类型中的初始设定值和代码，都将严格地进行计算。严格约束意味着所有表达式的结果都必须是 IEEE 754 算法对操作数预期的结果，以单精度和双精度格式表示。 &lt;/code&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;Java Code&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; FPTest {&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; strictfp &lt;span class="kwrd"&gt;double&lt;/span&gt; halfOfSquareFP(&lt;span class="kwrd"&gt;double&lt;/span&gt; n){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; n * 4.0  * 0.5;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; halfOfSquareNFP(&lt;span class="kwrd"&gt;double&lt;/span&gt; n){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; n * 4.0 * 0.5;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args) {&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;double&lt;/span&gt; d = 6.6e+307;&lt;br/&gt;    &lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(halfOfSquareFP(d));&lt;br/&gt;&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(halfOfSquareNFP(d)); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;span class="rem"&gt;//FPTest&lt;/span&gt;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;5、动态类加载&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Java中在运行时动态加载类的能力非常强大，动态类加载使得Java应用程序可以下载目标机器上没有的class文件。在一个机器上的对象类型可以无缝传输到其它机器。新的类型可以引入远程机器，可以在运行时扩展远程应用程序的行为。如下例子演示了远程应用程序接收类型实现某个接口：&lt;/p&gt;Java Code&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyRMIServer extends UnicastRemoteObject&lt;br/&gt;    implements SomeInterface {&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; MyRMIServer() throws RemoteException{ super();}&lt;br/&gt;&lt;br/&gt;      &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; String obtainName(IStockTicker ticker){&lt;br/&gt;&lt;br/&gt;    String stock_ticker = ticker.getTicker(); &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(stock_ticker.equalsIgnoreCase(&lt;span class="str"&gt;&amp;quot;MSFT&amp;quot;&lt;/span&gt;))&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Microsoft Corporation&amp;quot;&lt;/span&gt;; &lt;br/&gt;    &lt;span class="kwrd"&gt;else&lt;/span&gt;  &lt;span class="kwrd"&gt;if&lt;/span&gt;(stock_ticker.equalsIgnoreCase(&lt;span class="str"&gt;&amp;quot;SUNW&amp;quot;&lt;/span&gt;)) &lt;br/&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Sun Microsystems&amp;quot;&lt;/span&gt;; &lt;br/&gt;    &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br/&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Unknown Stock Ticker&amp;quot;&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;    }&lt;span class="rem"&gt;/* obtainName(IStockTicker) */&lt;/span&gt;&lt;br/&gt;    &lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;obtainName() 远程方法接收实现IStockTicker接口的类型，远程客户端可以调用这个方法然后传入实现IStockTicker的类型，例如NASDAQStock，如果MyRMIServer 所谓远程机器没有类的话，整个NASDAQStock 需要的类都会自动传输到远程机器。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;6、包含字段的接口&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;在Java中，接口中可以声明常量，在实现的类中可以使用这个常量，这在C#中是没有的。这其实无关紧要，因为原先要这么这么用的主要原因是模拟枚举。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;7、匿名内部类&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;匿名内部类是类的声明位于类创建实例内的类。匿名内部类一般用于在应用程序中只会有一个类的实例，最常用的就是在GUI类库中指定回调。如下是使用匿名内部类来实现状态设计模式的例子：&lt;/p&gt;Java Code&lt;br/&gt;&lt;br/&gt; &lt;span class="rem"&gt;/* An instance of this class represents the current state of a ClientView GUI. */&lt;/span&gt;&lt;br/&gt;  &lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ClientState{&lt;br/&gt;&lt;br/&gt;     &lt;span class="rem"&gt;// This instance of the class is used to signify that the user is not logged in.&lt;/span&gt;&lt;br/&gt;     &lt;span class="rem"&gt;// The only thing a user can do in this state is login and exit.  &lt;/span&gt;&lt;br/&gt;     &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; ClientState NOT_LOGGED_IN = &lt;span class="kwrd"&gt;new&lt;/span&gt; ClientState() {&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; setMenuState(ClientView cv) {&lt;br/&gt;            &lt;br/&gt;        cv.setMenuEnabledState(&lt;span class="kwrd"&gt;false&lt;/span&gt;); &lt;span class="rem"&gt;/* disable all menus */&lt;/span&gt;&lt;br/&gt;        cv.menuLogin.setEnabled(&lt;span class="kwrd"&gt;true&lt;/span&gt;); &lt;br/&gt;        cv.menuExit.setEnabled(&lt;span class="kwrd"&gt;true&lt;/span&gt;); &lt;br/&gt;&lt;br/&gt;        &lt;span class="rem"&gt;//can't type &lt;/span&gt;&lt;br/&gt;        cv.textArea.setEnabled(&lt;span class="kwrd"&gt;false&lt;/span&gt;); &lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; String toString(){&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;ClientState: NOT_LOGGED_IN&amp;quot;&lt;/span&gt;; &lt;br/&gt;        }&lt;br/&gt;    };&lt;br/&gt;    &lt;br/&gt;    &lt;br/&gt;     &lt;span class="rem"&gt;// This instance of the class is used to signify that the user is logged in&lt;/span&gt;&lt;br/&gt;     &lt;span class="rem"&gt;// but has not yet created a document to work with. The user cannot type or save &lt;/span&gt;&lt;br/&gt;     &lt;span class="rem"&gt;// anything in this mode. &lt;/span&gt;&lt;br/&gt;     &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; ClientState NO_OPEN_DOCUMENT = &lt;span class="kwrd"&gt;new&lt;/span&gt; ClientState() {&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; setMenuState(ClientView cv) {&lt;br/&gt;            &lt;br/&gt;        cv.setMenuEnabledState(&lt;span class="kwrd"&gt;false&lt;/span&gt;); &lt;span class="rem"&gt;/* disable all menus */&lt;/span&gt;&lt;br/&gt;        cv.menuLogin.setEnabled(&lt;span class="kwrd"&gt;true&lt;/span&gt;); &lt;br/&gt;        cv.menuExit.setEnabled(&lt;span class="kwrd"&gt;true&lt;/span&gt;); &lt;br/&gt;        cv.menuOpenFile.setEnabled(&lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;br/&gt;        cv.menuNewFile.setEnabled(&lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;        &lt;span class="rem"&gt;//can't type &lt;/span&gt;&lt;br/&gt;        cv.textArea.setEnabled(&lt;span class="kwrd"&gt;false&lt;/span&gt;); &lt;br/&gt;&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; String toString(){&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;ClientState: NO_OPEN_DOCUMENT&amp;quot;&lt;/span&gt;; &lt;br/&gt;        }&lt;br/&gt;    }; &lt;br/&gt;    &lt;br/&gt;    &lt;br/&gt;     &lt;span class="rem"&gt;// This instance of the class is used to signify that the user is editting a file. &lt;/span&gt;&lt;br/&gt;     &lt;span class="rem"&gt;// In this mode the user can use any functionality he/she sees fit. &lt;/span&gt;&lt;br/&gt;     &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; ClientState EDITTING_DOCUMENT = &lt;span class="kwrd"&gt;new&lt;/span&gt; ClientState() {&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; setMenuState(ClientView cv) {&lt;br/&gt;            &lt;br/&gt;        cv.setMenuEnabledState(&lt;span class="kwrd"&gt;true&lt;/span&gt;);   /* enable all menus             &lt;br/&gt;        cv.textArea.setEnabled(&lt;span class="kwrd"&gt;true&lt;/span&gt;); &lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; String toString(){&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;ClientState:EDITTING_DOCUMENT&amp;quot;&lt;/span&gt;; &lt;br/&gt;        }&lt;br/&gt;    }; &lt;br/&gt;&lt;br/&gt;   &lt;br/&gt;     &lt;br/&gt;     &lt;span class="rem"&gt;// Default constructor private to stop people from directly creating instances &lt;/span&gt;&lt;br/&gt;     &lt;span class="rem"&gt;// of the class.        &lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; ClientState() {;}&lt;br/&gt;&lt;br/&gt;    &lt;br/&gt;     &lt;span class="rem"&gt;// This disables various elements of the ClientView's menu dependent on which&lt;/span&gt;&lt;br/&gt;     &lt;span class="rem"&gt;// ClientState object this is.      &lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; setMenuState(ClientView cv);&lt;br/&gt;&lt;br/&gt;} &lt;span class="rem"&gt;// ClientState&lt;/span&gt;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;如下是使用ClientState类的例子&lt;/p&gt;    &lt;span class="kwrd"&gt;bool&lt;/span&gt; loginUser(String username, String passwd) {&lt;br/&gt;&lt;br/&gt;        &lt;span class="rem"&gt;//check if already logged in&lt;/span&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;(myGUI.state == ClientState.NOT_LOGGED_IN)  &lt;br/&gt;          &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;        &lt;span class="rem"&gt;//enable parts of the GUI if the user authenticates&lt;/span&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;(userAuthenticated(username, passwd)){&lt;br/&gt;&lt;br/&gt;              myGUI.state = ClientState.NO_OPEN_DOCUMENT; &lt;br/&gt;              myGUI.state.setMenuState(myView); &lt;br/&gt;              &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;; &lt;br/&gt;    &lt;br/&gt; &lt;br/&gt;   }&lt;span class="rem"&gt;/* loginUser(String, String) */&lt;/span&gt;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;8、静态导入&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;静态导入特性使我们可以访问类静态成员的时候不需要指定类名，这个特性可以让我们减少代码的冗余，特别对于某些帮助类型来说很方便。静态导入和普通的import语句很像，只不过多了static关键字，导入的是类而不是包名。&lt;/p&gt;Java Code&lt;br/&gt;import &lt;span class="kwrd"&gt;static&lt;/span&gt; java.awt.Color.*; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args) throws Exception{&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//constants not qualified thanks to static import&lt;/span&gt;&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(RED + &lt;span class="str"&gt;&amp;quot; plus &amp;quot;&lt;/span&gt; + YELLOW + &lt;span class="str"&gt;&amp;quot; is &amp;quot;&lt;/span&gt; + ORANGE);&lt;br/&gt;    }&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;输出：&lt;/p&gt;&lt;p&gt;java.awt.Color[r=255,g=0,b=0] plus java.awt.Color[r=255,g=255,b=0] is java.awt.Color[r=255,g=200,b=0] &lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;参考&lt;/p&gt;&lt;ol&gt;  &lt;li&gt;Eckel, Bruce. &lt;span style="text-decoration: underline"&gt;Thinking In Java.&lt;/span&gt; Prentice Hall, 2000. &lt;/li&gt;  &lt;li&gt;Gunnerson, Eric. &lt;span style="text-decoration: underline"&gt;A Programmer's Introduction To C#.&lt;/span&gt; Apress, 2001. &lt;/li&gt;  &lt;li&gt;Sun Microsystems. &lt;span style="text-decoration: underline"&gt;The Java™ Tutorial.&lt;/span&gt;&amp;lt;&lt;a href="http://java.sun.com/docs/books/tutorial/"&gt;http://java.sun.com/docs/books/tutorial/&lt;/a&gt;&amp;gt; &lt;/li&gt;  &lt;li&gt;Microsoft Corporation. &lt;span style="text-decoration: underline"&gt;.NET Framework Programming.&lt;/span&gt; &amp;lt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ms229284(VS.80).aspx"&gt; http://msdn2.microsoft.com/en-us/library/ms229284(VS.80).aspx&lt;/a&gt;&amp;gt; &lt;/li&gt;  &lt;li&gt;Microsoft Corporation. &lt;span style="text-decoration: underline"&gt;C# Language Reference.&lt;/span&gt; &amp;lt;&lt;a href="http://msdn2.microsoft.com/en-us/library/618ayhy6(VS.80).aspx"&gt; http://msdn2.microsoft.com/en-us/library/618ayhy6(VS.80).aspx&lt;/a&gt;&amp;gt; &lt;/li&gt;&lt;/ol&gt;&lt;img src="http://www.cnblogs.com/lovecindywang/aggbug/2345895.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lovecindywang/archive/2012/02/10/2345895.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lovecindywang/archive/2012/02/09/2344315.html</id><title type="text">【翻译】C#编程语言和JAVA编程语言的比较（上）</title><summary type="text">原文地址：http://www.25hoursaday.com/CsharpVsJava.html简介C#语言是一门面向对象的语言，开发者可以使用C#和微软.NET平台快速构建各种应用程序。C#和.NET平台的目标是把开发者从一些诸如内存管理、类型安全问题、底层类库、数组边界检查等等的底层问题中解放出来并节约大量的时间，这样开发者就可以真正把时间和精力放在他们的应用程序和业务逻辑上。对于Java开发者来说，把前面那句话的开头改为“Java语言和平台”，这句话也同样可以总结Java语言和平台。后面的内容介绍了C#和Java编程语言的异同，这些都是基于我使用两个语言的经历。所有代码都经过微软.NE</summary><published>2012-02-09T09:57:00Z</published><updated>2012-02-09T09:57:00Z</updated><author><name>lovecindywang</name><uri>http://www.cnblogs.com/lovecindywang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lovecindywang/archive/2012/02/09/2344315.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lovecindywang/archive/2012/02/09/2344315.html"/><content type="html">&lt;p&gt;原文地址：&lt;a title="http://www.25hoursaday.com/CsharpVsJava.html" href="http://www.25hoursaday.com/CsharpVsJava.html"&gt;http://www.25hoursaday.com/CsharpVsJava.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;简介&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#语言是一门面向对象的语言，开发者可以使用C#和微软.NET平台快速构建各种应用程序。C#和.NET平台的目标是把开发者从一些诸如内存管理、类型安全问题、底层类库、数组边界检查等等的底层问题中解放出来并节约大量的时间，这样开发者就可以真正把时间和精力放在他们的应用程序和业务逻辑上。对于Java开发者来说，把前面那句话的开头改为&amp;ldquo;Java语言和平台&amp;rdquo;，这句话也同样可以总结Java语言和平台。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;后面的内容介绍了C#和Java编程语言的异同，这些都是基于我使用两个语言的经历。所有代码都经过微软.NET框架2.0以及Java SE 6的测试。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;em&gt;注意：作者有些代码不符合.NET 3.5或JAVA SE 7（或以上）版本的最佳实践写法并且也不能覆盖它们所提供的新语法和新特性，但不影响本文的重点也就是平台的比较。&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第一部分：C#和JAVA基本一致的地方&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1、我们都是Object&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#的类层次中有一个根，也就是所有C#的类都是System.Object的子类，Java也是这样，所有类都是java.lang.Object的子类。两个语言的Object类的方法有些相同（比如System.Object的ToString()和java.lang.Object的toString()），也有一些不同（System.Object没有java.lang.Object中的wait()、notify()或notifyAll()）。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;em&gt;注意：在C#中object类可以写成object或Object。小写的object C#关键字在编译的时候会替换为System.Object。&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2、关键字一览&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Java和C#有很多语法很相似，除了throws、transient和strictfp几乎所有Java关键字都有C#的对应。下表示Java和C#的关键字对照表，Java关键字标红而C#关键字标蓝。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201202/201202091756596637.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201202/201202091757006562.png" alt="image" width="689" height="879" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;em&gt;注意：尽管goto和const是Java语言的关键字，但是在Java中并没有用到。C#中的&lt;code&gt;[NonSerialized]特性等价于Java中的transient关键字。&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;code&gt;3、虚拟机和语言运行时&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;code&gt;Java一般编译成Java字节码并运行于托管的执行环境（Java虚拟机、JVM），同样，C#代码编译成中间语言（IL）运行于公共语言运行时（CLR）。两个平台都通过JIT编译器提供本机编译。&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&lt;em&gt;注意：虽然Java平台支持字节码的解释和JIT编译两种方式，但是.NET平台只支持C#代码的本机执行，IL代码在运行前总是会编译成本机代码。&lt;/em&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;code&gt;4、基于堆和垃圾收集&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;code&gt;在Java中，对象使用new关键字创建在堆上。在C#中大多数类使用new关键字创建在堆上。和JVM一样，CLR也是通过标记和压缩垃圾回收算法管理销毁对象。&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&lt;em&gt;注意：C#还支持基于栈的类，叫做值类型，后文会介绍到这个。&lt;/em&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;code&gt;5、数组可以是交错的&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;code&gt;对于C或C++这样的语言，多维数组的每一个子数组都必须有相同的维度。在Java和C#中数组不必统一，交错数组可以认为是数组的一维数组。交错数组的项就是保持类型或引用的另一个数组，这样交错数组的行和列就不需要有统一的长度，如下代码所示：&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;span class="kwrd"&gt;int&lt;/span&gt; [][]myArray = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[2][]; &lt;br/&gt;  myArray[0] = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[3]; &lt;br/&gt;  myArray[1] = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[9];&lt;p&gt;&lt;span style="font-family: Courier New;"&gt;6、没有全局方法&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Courier New;"&gt;和Java一样，和C++不一样，C#中的方法必须是类的一部分，作为成员方法或静态方法。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Courier New;"&gt;7、有接口但没有多重继承&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Courier New;"&gt;C#和Java一样支持接口的概念，接口类似纯抽象类。C#和Java一样都支持类的单继承，但支持借口的多重继承（或实现）。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Courier New;"&gt;8、字符串不可变&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Courier New;"&gt;C#的System.String类和java.lang.String类相似。它们都是不可变的，也就是字符串的值在创建后一次都不能修改。字符串提供的一些实例方法看似可以修改字符串的内容，其实是创建了一个新的字符串并返回，原始的字符串并没有修改。如下的C#和Java代码都没有修改字符串：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;C# Code&lt;br/&gt;   String csString = &lt;span class="str"&gt;"Apple Jack"&lt;/span&gt;; &lt;br/&gt;   csString.ToLower(); &lt;br/&gt;Java Code&lt;br/&gt;   String jString = &lt;span class="str"&gt;"Grapes"&lt;/span&gt;; &lt;br/&gt;   jString.toLowerCase(); &lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;code&gt;9、密封类&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;code&gt;Java和C#都提供了一种机制确保类是继承体系中的最后一个，不可以有子类。在Java中可以为类修饰final关键字，而C#则通过sealed关键字修饰类。如下是两种语言密封类的例子：&lt;/code&gt;&lt;/p&gt;C# Code&lt;br/&gt; &lt;span class="kwrd"&gt;sealed&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Student {&lt;br/&gt;   &lt;span class="kwrd"&gt;string&lt;/span&gt; fname;&lt;br/&gt;   &lt;span class="kwrd"&gt;string&lt;/span&gt; lname;&lt;br/&gt;   &lt;span class="kwrd"&gt;int&lt;/span&gt; uid;&lt;br/&gt;   &lt;span class="kwrd"&gt;void&lt;/span&gt; attendClass() {}&lt;br/&gt;} &lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt; final &lt;span class="kwrd"&gt;class&lt;/span&gt; Student {&lt;br/&gt;   String fname;&lt;br/&gt;   String lname;&lt;br/&gt;   &lt;span class="kwrd"&gt;int&lt;/span&gt; uid;&lt;br/&gt;   &lt;span class="kwrd"&gt;void&lt;/span&gt; attendClass() {}&lt;br/&gt;} &lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;10、抛出和捕获异常&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#和Java的异常有很多相似的地方。两种语言都使用try块来表示需要守护的区域，catch块来处理抛出的异常，finally块在离开方法之前释放资源。两种语言都有继承体系，所有的异常都从一个Exception类继承。并且都可以在捕获到异常并进行了一些错误处理之后重新抛出异常。最后，它们都提供了机制把异常包装成另外一个异常，这样就可以捕获到一个异常后抛出另一个异常。这里可以举一个例子，比如三层结构的应用程序，数据访问的时候捕获到了一个SQLException，可以抛出一个应用程序相关的异常。这样的话，应用程序异常可以使用原始的SQLException来初始化，处理应用程序异常的时候如果需要还可以访问到原始的异常。如下代码演示了两种语言在异常方面的相似：&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; MyException: Exception{&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; MyException(&lt;span class="kwrd"&gt;string&lt;/span&gt; message): &lt;span class="kwrd"&gt;base&lt;/span&gt;(message){ }&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; MyException(&lt;span class="kwrd"&gt;string&lt;/span&gt; message, Exception innerException): &lt;br/&gt;    &lt;span class="kwrd"&gt;base&lt;/span&gt;(message, innerException){ }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ExceptionTest {&lt;br/&gt;    &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoStuff(){  &lt;br/&gt;    &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; FileNotFoundException();  &lt;br/&gt;    }&lt;br/&gt;    &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;try&lt;/span&gt;{            &lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;try&lt;/span&gt;{        &lt;br/&gt;        &lt;br/&gt;        DoStuff(); &lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt;;  &lt;span class="rem"&gt;//won't get to execute &lt;/span&gt;&lt;br/&gt;&lt;br/&gt;        }&lt;span class="kwrd"&gt;catch&lt;/span&gt;(IOException ioe){ &lt;span class="rem"&gt;/* parent of FileNotFoundException */&lt;/span&gt; &lt;br/&gt;        &lt;br/&gt;        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; MyException(&lt;span class="str"&gt;"MyException occured"&lt;/span&gt;, ioe); &lt;span class="rem"&gt;/* rethrow new exception with inner exception specified */&lt;/span&gt;&lt;br/&gt;        }&lt;br/&gt;        &lt;br/&gt;    }&lt;span class="kwrd"&gt;finally&lt;/span&gt;{&lt;br/&gt;        &lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;"***Finally block executes even though MyException not caught***"&lt;/span&gt;);&lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;    &lt;br/&gt;}&lt;span class="rem"&gt;//Main(string[])&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;} &lt;span class="rem"&gt;// ExceptionTest&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; MyException extends Exception{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; MyException(String message){ super(message); }&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; MyException(String message, Exception innerException){ super(message, innerException); }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ExceptionTest {&lt;br/&gt;    &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; doStuff(){  &lt;br/&gt;    &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArithmeticException();    &lt;br/&gt;    }&lt;br/&gt;    &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args) throws Exception{&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;try&lt;/span&gt;{            &lt;br/&gt;        &lt;br/&gt;        &lt;span class="kwrd"&gt;try&lt;/span&gt;{        &lt;br/&gt;        &lt;br/&gt;        doStuff(); &lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt;;  &lt;span class="rem"&gt;//won't get to execute &lt;/span&gt;&lt;br/&gt;        &lt;br/&gt;        }&lt;span class="kwrd"&gt;catch&lt;/span&gt;(RuntimeException re){ &lt;span class="rem"&gt;/* parent of ArithmeticException */&lt;/span&gt; &lt;br/&gt;        &lt;br/&gt;        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; MyException(&lt;span class="str"&gt;"MyException occured"&lt;/span&gt;, re); &lt;span class="rem"&gt;/* rethrow new exception with cause specified */&lt;/span&gt;&lt;br/&gt;        }&lt;br/&gt;        &lt;br/&gt;    }&lt;span class="kwrd"&gt;finally&lt;/span&gt;{&lt;br/&gt;        &lt;br/&gt;        System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"***Finally block executes even though MyException not caught***"&lt;/span&gt;);&lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;    &lt;br/&gt;}&lt;span class="rem"&gt;//main(string[])&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;} &lt;span class="rem"&gt;// ExceptionTest&lt;/span&gt;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;11、定义的时候进行成员初始化和静态构造方法&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#和Java中都可以在定义实例和静态变量的时候进行初始化。如果成员变量是实例变量则在构造方法执行之前调用，静态成员则在第一次使用成员以及第一次创建类实例之前初始化。还可以指定一段代码在类创建之前或静态方法调用之前被调用。这段代码在C中叫做静态构造方法而在Java中叫做静态初始化块。静态构造方法会在第一次调用类的静态方法或第一次创建类实例之前调用。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; StaticInitTest{&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; instMember = InitInstance(); &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; staMember = InitStatic(); &lt;br/&gt;    &lt;br/&gt;&lt;br/&gt;    StaticInitTest(){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"In instance constructor"&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; StaticInitTest(){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"In static constructor"&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; String InitInstance(){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Initializing instance variable"&lt;/span&gt;);&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;"instance"&lt;/span&gt;;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;static&lt;/span&gt; String InitStatic(){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Initializing static variable"&lt;/span&gt;);&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;"static"&lt;/span&gt;;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoStuff(){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Invoking static DoStuff() method"&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Beginning main()"&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    StaticInitTest.DoStuff(); &lt;br/&gt;    &lt;br/&gt;    StaticInitTest sti = &lt;span class="kwrd"&gt;new&lt;/span&gt; StaticInitTest(); &lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Completed main()"&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Main{&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    String instMember = initInstance(); &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; String staMember = initStatic(); &lt;br/&gt;    &lt;br/&gt;&lt;br/&gt;    Main(){&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"In instance constructor"&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt;{&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"In static constructor"&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; String initInstance(){&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Initializing instance variable"&lt;/span&gt;);&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;"instance"&lt;/span&gt;;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;static&lt;/span&gt; String initStatic(){&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Initializing static variable"&lt;/span&gt;);&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;"static"&lt;/span&gt;;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; doStuff(){&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Invoking static DoStuff() method"&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args){&lt;br/&gt;&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Beginning main()"&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    Main.doStuff(); &lt;br/&gt;    &lt;br/&gt;    Main sti = &lt;span class="kwrd"&gt;new&lt;/span&gt; Main(); &lt;br/&gt;&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Completed main()"&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;代码执行结果：&lt;/p&gt;&lt;p&gt;Initializing static variable &lt;br /&gt;In static constructor &lt;br /&gt;Beginning main() &lt;br /&gt;Invoking static DoStuff() method &lt;br /&gt;Initializing instance variable &lt;br /&gt;In instance constructor &lt;br /&gt;Completed main()&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;em&gt;注意：这里作者的代码有误，小小修改了一下&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;12、装箱&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在某些情况下，值类型需要当做对象，.NET和Java运行时会自动把值类型转换成在堆上分配的引用类型，这个过程叫做装箱。自动把对象转换成相应的值类型的过程叫做拆箱，比如把java.lang.Integer的实例转换成int。如下例子演示了运行时发生装箱的各种情况：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections;&lt;br/&gt;&lt;br/&gt;&lt;span class="rem"&gt;//分配在栈上的结构需要装箱才能当做object&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;struct&lt;/span&gt; Point{&lt;br/&gt;&lt;br/&gt;  &lt;span class="rem"&gt;//member fields &lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; x; &lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; y; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Point (&lt;span class="kwrd"&gt;int&lt;/span&gt; x, &lt;span class="kwrd"&gt;int&lt;/span&gt; y){&lt;br/&gt;  &lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.x = x;&lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.y = y; &lt;br/&gt;&lt;br/&gt;    } &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ToString(){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; String.Format(&lt;span class="str"&gt;"({0}, {1})"&lt;/span&gt;, x, y); &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;}&lt;span class="rem"&gt;//Point&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PrintString(&lt;span class="kwrd"&gt;object&lt;/span&gt; o){&lt;br/&gt;&lt;br/&gt;     Console.WriteLine(o);&lt;br/&gt;&lt;br/&gt;     }&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;       Point p = &lt;span class="kwrd"&gt;new&lt;/span&gt; Point(10, 15); &lt;br/&gt;       ArrayList list = &lt;span class="kwrd"&gt;new&lt;/span&gt; ArrayList(); &lt;br/&gt;       &lt;span class="kwrd"&gt;int&lt;/span&gt; z = 100;&lt;br/&gt;&lt;br/&gt;       PrintString(p); &lt;span class="rem"&gt;//p在传参的时候装箱了&lt;/span&gt;&lt;br/&gt;       PrintString(z); &lt;span class="rem"&gt;//z在传参的时候装箱了&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;       &lt;span class="rem"&gt;// 在保存到集合的时候int和float装箱了&lt;/span&gt;&lt;br/&gt;       &lt;span class="rem"&gt;// 不需要Java的包装类 &lt;/span&gt;&lt;br/&gt;       list.Add(1); &lt;br/&gt;       list.Add(13.12); &lt;br/&gt;       list.Add(z); &lt;br/&gt;       &lt;br/&gt;       &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i =0; i &amp;lt; list.Count; i++)&lt;br/&gt;       PrintString(list[i]);    &lt;br/&gt;       &lt;br/&gt;     }&lt;br/&gt;&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;Java Code&lt;br/&gt;import java.util.*;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PrintString(Object o){&lt;br/&gt;&lt;br/&gt; System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(o);&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PrintInt(&lt;span class="kwrd"&gt;int&lt;/span&gt; i){&lt;br/&gt;&lt;br/&gt; System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(i); &lt;br/&gt;  &lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args){&lt;br/&gt;&lt;br/&gt; Vector list = &lt;span class="kwrd"&gt;new&lt;/span&gt; Vector(); &lt;br/&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; z = 100;&lt;br/&gt; Integer x = &lt;span class="kwrd"&gt;new&lt;/span&gt; Integer(300);&lt;br/&gt; PrintString(z); &lt;span class="rem"&gt;//z boxed to object when passed to PrintString&lt;/span&gt;&lt;br/&gt; PrintInt(x); &lt;span class="rem"&gt;//x unboxed to int when passed to PrintInt&lt;/span&gt;&lt;br/&gt;&lt;br/&gt; &lt;span class="rem"&gt;// integers and float boxed when stored in collection &lt;/span&gt;&lt;br/&gt; &lt;span class="rem"&gt;// therefore no need for Java wrapper classes &lt;/span&gt;&lt;br/&gt; list.add(1); &lt;br/&gt; list.add(13.12); &lt;br/&gt; list.add(z); &lt;br/&gt;       &lt;br/&gt; &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i =0; i &amp;lt; list.size(); i++)&lt;br/&gt;   PrintString(list.elementAt(i));    &lt;br/&gt;       &lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第二部分：C#和JAVA基本一致但语法不同的地方&lt;/strong&gt; &lt;/p&gt;&lt;p&gt;1、Main方法&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#和Java程序的入口点都是main方法。表面区别是C#的Main方法是大写的M（.NET框架的方法名的惯例），而Java中的main方法是小写字母m（同样也是Java方法的惯例）。还有一个区别就是C#的Main()方法可以没有参数。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;C# Code&lt;br/&gt; &lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; A{&lt;br/&gt;   &lt;br/&gt;   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(String[] args){&lt;br/&gt;   &lt;br/&gt;     Console.WriteLine(&lt;span class="str"&gt;"Hello World"&lt;/span&gt;); &lt;br/&gt;   &lt;br/&gt;   }&lt;br/&gt;} &lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; B{&lt;br/&gt;   &lt;br/&gt;   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args){&lt;br/&gt;   &lt;br/&gt;     System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Hello World"&lt;/span&gt;); &lt;br/&gt;   &lt;br/&gt;   }&lt;br/&gt;} &lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一般推荐应用程序的每一个类都有一个main方法来测试类的功能，比如可能有两个类A和B都包含main方法。在Java中，类是编译的单元，只需要通过命令行指定需要运行的类，在C#中也可以使用/main开关编译应用程序指定应用程序创建时使用哪个main作为入口点实现相同的效果。使用main以及预处理指令条件编译是不错的测试技术。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;Java Example&lt;br/&gt;C:\CodeSample&amp;gt; javac A.java B.java &lt;br/&gt;&lt;br/&gt;C:\CodeSample&amp;gt; java A&lt;br/&gt; Hello World from &lt;span class="kwrd"&gt;class&lt;/span&gt; A&lt;br/&gt;&lt;br/&gt;C:\CodeSample&amp;gt; java B&lt;br/&gt; Hello World from &lt;span class="kwrd"&gt;class&lt;/span&gt; B&lt;br/&gt;&lt;br/&gt;C# Example&lt;br/&gt;C:\CodeSample&amp;gt; csc /main:A /&lt;span class="kwrd"&gt;out&lt;/span&gt;:example.exe A.cs B.cs &lt;br/&gt;&lt;br/&gt;C:\CodeSample&amp;gt; example.exe&lt;br/&gt; Hello World from &lt;span class="kwrd"&gt;class&lt;/span&gt; A&lt;br/&gt;&lt;br/&gt;C:\CodeSample&amp;gt; csc /main:B /&lt;span class="kwrd"&gt;out&lt;/span&gt;:example.exe A.cs B.cs &lt;br/&gt;&lt;br/&gt;C:\CodeSample&amp;gt; example.exe&lt;br/&gt; Hello World from &lt;span class="kwrd"&gt;class&lt;/span&gt; B&lt;p&gt;&lt;br /&gt;对于Java，改变使用的main不需要进行重新编译，而C#应用程序需要重新编译。但是，从另一方面来说，Java又不支持条件编译，main方法可能就会带入发行版本中。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2、继承语法&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#对于继承使用了C++的语法，都使用冒号来实现继承和接口实现，在Java中则是extends和implements关键字。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;C# Code&lt;br/&gt; &lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; B:A, IComparable{&lt;br/&gt;   &lt;br/&gt;  &lt;span class="kwrd"&gt;int&lt;/span&gt; CompareTo(){}&lt;br/&gt;&lt;br/&gt;   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(String[] args){&lt;br/&gt;   &lt;br/&gt;     Console.WriteLine(&lt;span class="str"&gt;"Hello World"&lt;/span&gt;); &lt;br/&gt;   &lt;br/&gt;   }&lt;br/&gt;} &lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; B extends A implements Comparable{&lt;br/&gt;   &lt;br/&gt;   &lt;span class="kwrd"&gt;int&lt;/span&gt; compareTo(){}&lt;br/&gt;&lt;br/&gt;   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args){&lt;br/&gt;   &lt;br/&gt;     System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Hello World"&lt;/span&gt;); &lt;br/&gt;   &lt;br/&gt;   }&lt;br/&gt;} &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#的这种语法更符合从C++转来开发者的习惯，而Java的语法则可以通过类的声明直接知道类是子类呢还是只是实现了接口，C#则无法区分。但是我们知道根据.NET的命名约定，接口需要以大写的字母I打头，比如ICloneable，这样就不会有这个问题了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;3、运行时类型标识（is操作符）&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#的js操作符和Java的instanceof操作符一样。如下代码等价：&lt;/p&gt;C# Code&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;if&lt;/span&gt;(x &lt;span class="kwrd"&gt;is&lt;/span&gt; MyClass)&lt;br/&gt;   MyClass mc = (MyClass) x;&lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;if&lt;/span&gt;(x instanceof MyClass)&lt;br/&gt;   MyClass mc = (MyClass) x;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;4、命名空间&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#命名空间是对类进行分组的方式，和Java的包构造差不多。使用C++的人会发现C#命名空间和C++的差不多，在Java中，包名字代笔应用程序中源文件目录结构，而C#的命名空间则不会要求源文件的物理层次和逻辑结构有关联：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;C# Code&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;namespace&lt;/span&gt; com.carnage4life{&lt;br/&gt;&lt;br/&gt;   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyClass {&lt;br/&gt; &lt;br/&gt;   &lt;span class="kwrd"&gt;int&lt;/span&gt; x; &lt;br/&gt;&lt;br/&gt;   &lt;span class="kwrd"&gt;void&lt;/span&gt; doStuff(){}&lt;br/&gt;&lt;br/&gt;   }&lt;br/&gt;&lt;br/&gt; }&lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt;  package com.carnage4life;&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyClass {&lt;br/&gt; &lt;br/&gt;  &lt;span class="kwrd"&gt;int&lt;/span&gt; x; &lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;void&lt;/span&gt; doStuff(){}&lt;br/&gt;&lt;br/&gt; }&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;C#的命名空间语法允许进行命名空间的嵌套，如下：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;C# Code&lt;br/&gt;  &lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;namespace&lt;/span&gt; Company{&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyClass { &lt;span class="rem"&gt;/* Company.MyClass */&lt;/span&gt; &lt;br/&gt; &lt;br/&gt;        &lt;span class="kwrd"&gt;int&lt;/span&gt; x; &lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; doStuff(){}&lt;br/&gt;&lt;br/&gt;        } &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;namespace&lt;/span&gt; Carnage4life{&lt;br/&gt;    &lt;br/&gt;       &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyOtherClass {  &lt;span class="rem"&gt;/* Company.Carnage4life.MyOtherClass */&lt;/span&gt; &lt;br/&gt; &lt;br/&gt;        &lt;span class="kwrd"&gt;int&lt;/span&gt; y; &lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; doOtherStuff(){}&lt;br/&gt;    &lt;br/&gt;       &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;    &lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;"Hey, I can nest namespaces"&lt;/span&gt;); &lt;br/&gt;       }&lt;br/&gt;&lt;br/&gt;      }&lt;span class="rem"&gt;// class MyOtherClass&lt;/span&gt;&lt;br/&gt;       }&lt;span class="rem"&gt;// namespace Carnage4life&lt;/span&gt;&lt;br/&gt;   }// &lt;span class="kwrd"&gt;namespace&lt;/span&gt; Company &lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;5、构造方法、析构方法以及终结器&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#中的构造方法的语法和语义和Java一样。C#还有析构方法的概念，这和C++的析构器语法比较相似，和Java的终结器语义一致。尽管存在析构方法这样的语法，但是还是不推荐使用，有许多原因。首先我们没有办法控制它运行的时间，如果在析构方法里面还持有其它引用的话情况更复杂，其次还会带来性能问题，因为垃圾回收线程不能直接回收带有析构方法的对象，必须等到终结器线程执行之后才可以回收，这样具有析构方法的对象可能比没有析构方法的对象存在的时间更长。如下是C#和Java的例子：&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyClass {&lt;br/&gt; &lt;br/&gt;     &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; num_created = 0; &lt;br/&gt;     &lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0;    &lt;br/&gt;&lt;br/&gt;      MyClass(){  &lt;br/&gt;        i = ++num_created; &lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;"Created object #"&lt;/span&gt; + i);    &lt;br/&gt;     }&lt;br/&gt;&lt;br/&gt;     ~MyClass(){&lt;br/&gt;         Console.WriteLine(&lt;span class="str"&gt;"Object #"&lt;/span&gt; + i + &lt;span class="str"&gt;" is being finalized"&lt;/span&gt;);  &lt;br/&gt;     }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i=0; i &amp;lt; 10000; i++)&lt;br/&gt;      &lt;span class="kwrd"&gt;new&lt;/span&gt; MyClass(); &lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;   }&lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyClass {&lt;br/&gt; &lt;br/&gt;     &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; num_created = 0; &lt;br/&gt;     &lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0;    &lt;br/&gt;&lt;br/&gt;      MyClass(){  &lt;br/&gt;        i = ++num_created; &lt;br/&gt;        System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Created object #"&lt;/span&gt; + i);    &lt;br/&gt;     }&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; finalize(){&lt;br/&gt;        System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Object #"&lt;/span&gt; + i + &lt;span class="str"&gt;" is being finalized"&lt;/span&gt;);  &lt;br/&gt;     }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i=0; i &amp;lt; 10000; i++)&lt;br/&gt;      &lt;span class="kwrd"&gt;new&lt;/span&gt; MyClass(); &lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;   }&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;em&gt;注意：在C#中析构方法（终结器）会在执行后自动调用基类的终结器，Java中不会。&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;6、同步方法和代码块&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在Java中可以指定同步块来确保在同一时刻只有一个线程访问某个对象，C#提供了lock语句对应Java的synchronized语句。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;C# Code&lt;br/&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; WithdrawAmount(&lt;span class="kwrd"&gt;int&lt;/span&gt; num){ &lt;br/&gt;&lt;br/&gt;   &lt;span class="kwrd"&gt;lock&lt;/span&gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt;){ &lt;br/&gt;&lt;br/&gt;   &lt;span class="kwrd"&gt;if&lt;/span&gt;(num &amp;lt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.amount)&lt;br/&gt;     &lt;span class="kwrd"&gt;this&lt;/span&gt;.amount -= num; &lt;br/&gt;&lt;br/&gt;   }&lt;br/&gt;&lt;br/&gt; }&lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; withdrawAmount(&lt;span class="kwrd"&gt;int&lt;/span&gt; num){ &lt;br/&gt;&lt;br/&gt;   synchronized(&lt;span class="kwrd"&gt;this&lt;/span&gt;){ &lt;br/&gt;&lt;br/&gt;   &lt;span class="kwrd"&gt;if&lt;/span&gt;(num &amp;lt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.amount)&lt;br/&gt;     &lt;span class="kwrd"&gt;this&lt;/span&gt;.amount -= num; &lt;br/&gt;&lt;br/&gt;   }&lt;br/&gt;&lt;br/&gt; }&lt;p&gt;C#和Java都有同步方法的概念。在调用同步方法的时候，调用方法的线程会锁定包含方法的对象，因此其它线程调用相同对象的同步方法必须等到其它线程执行完方法释放锁之后才能执行。同步方法在Java中用synchronized关键字来标记，而在C#中使用[MethodImpl(MethodImplOptions.Synchronized)]特性来修饰。同步方法的例子如下：&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Runtime.CompilerServices;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; BankAccount{&lt;br/&gt;&lt;br/&gt; [MethodImpl(MethodImplOptions.Synchronized)]&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; WithdrawAmount(&lt;span class="kwrd"&gt;int&lt;/span&gt; num){ &lt;br/&gt;&lt;br/&gt;   &lt;span class="kwrd"&gt;if&lt;/span&gt;(num &amp;lt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.amount)&lt;br/&gt;     &lt;span class="kwrd"&gt;this&lt;/span&gt;.amount - num; &lt;br/&gt;&lt;br/&gt; }&lt;br/&gt;&lt;br/&gt;}&lt;span class="rem"&gt;//BankAccount&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; BankAccount{&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; synchronized &lt;span class="kwrd"&gt;void&lt;/span&gt; withdrawAmount(&lt;span class="kwrd"&gt;int&lt;/span&gt; num){ &lt;br/&gt;&lt;br/&gt;   &lt;span class="kwrd"&gt;if&lt;/span&gt;(num &amp;lt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.amount)&lt;br/&gt;     &lt;span class="kwrd"&gt;this&lt;/span&gt;.amount - num; &lt;br/&gt;&lt;br/&gt; }&lt;br/&gt;&lt;br/&gt;}//BankAccount&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;7、访问修饰符&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;如下表格对照C#和Java的访问修饰符。C++爱好者比较失望，在Java2中Sun改变了protected关键字的语义，而C#的protected关键字和C++的一样。也就是说，protected成员只有在类的成员方法或派生类的成员方法中可以访问。internal修饰符表示成员可以被类相同程序集的其它类访问。internal protected修饰符表示的是internal或protected。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201202/201202091757001578.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201202/201202091757002135.png" alt="image" width="444" height="262" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;注意：在没有指定访问修饰符的情况下，C#字段或方法的默认访问级别是private，而Java则是protected。&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;8、反射&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在C#和Java中发现类中方法和字段以及运行时调用类方法的能力一般叫做反射。Java和C#中反射的主要区别是，C#的反射是程序集级别的，而Java是类级别的。由于程序集一般保存为DLL，对于C#需要包含类的DLL，而Java需要可以加载类文件或目标类。如下例子遍历某个类的方法，以此比较C#和Java在反射上的差异：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;C# Code&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Xml; &lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Reflection;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; ReflectionSample {&lt;br/&gt;&lt;br/&gt;   &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main( &lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    Assembly assembly=&lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br/&gt;    Type type=&lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br/&gt;    XmlDocument doc=&lt;span class="kwrd"&gt;null&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;try&lt;/span&gt;{&lt;br/&gt;        &lt;span class="rem"&gt;// 加载程序集以获得类型&lt;/span&gt;&lt;br/&gt;        assembly = Assembly.LoadFrom(&lt;span class="str"&gt;"C:\\WINNT\\Microsoft.NET\\Framework\\v1.0.2914\\System.XML.dll"&lt;/span&gt;);&lt;br/&gt;        type = assembly.GetType(&lt;span class="str"&gt;"System.Xml.XmlDocument"&lt;/span&gt;, &lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;        &lt;span class="rem"&gt;//Unfortunately one cannot dynamically instantiate types via the Type object in C#. &lt;/span&gt;&lt;br/&gt;        doc  =  Activator.CreateInstance(&lt;span class="str"&gt;"System.Xml"&lt;/span&gt;,&lt;span class="str"&gt;"System.Xml.XmlDocument"&lt;/span&gt;).Unwrap() &lt;span class="kwrd"&gt;as&lt;/span&gt; XmlDocument;&lt;br/&gt;&lt;br/&gt;          &lt;span class="kwrd"&gt;if&lt;/span&gt;(doc != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br/&gt;                 Console.WriteLine(doc.GetType() + &lt;span class="str"&gt;" was created at runtime"&lt;/span&gt;);&lt;br/&gt;              &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br/&gt;                 Console.WriteLine(&lt;span class="str"&gt;"Could not dynamically create object at runtime"&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    }&lt;span class="kwrd"&gt;catch&lt;/span&gt;(FileNotFoundException){&lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;"Could not load Assembly: system.xml.dll"&lt;/span&gt;);&lt;br/&gt;         &lt;span class="kwrd"&gt;return&lt;/span&gt;;&lt;br/&gt;    }&lt;span class="kwrd"&gt;catch&lt;/span&gt;(TypeLoadException){&lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;"Could not load Type: System.Xml.XmlDocument from assembly: system.xml.dll"&lt;/span&gt;);&lt;br/&gt;        &lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt;;&lt;br/&gt;    }&lt;span class="kwrd"&gt;catch&lt;/span&gt;(MissingMethodException){&lt;br/&gt;       Console.WriteLine(&lt;span class="str"&gt;"Cannot find default constructor of "&lt;/span&gt; + type);&lt;br/&gt;       }&lt;span class="kwrd"&gt;catch&lt;/span&gt;(MemberAccessException){&lt;br/&gt;       Console.WriteLine(&lt;span class="str"&gt;"Could not create new XmlDocument instance"&lt;/span&gt;);&lt;br/&gt;       }&lt;br/&gt;    &lt;br/&gt;    &lt;span class="rem"&gt;// 获得方法&lt;/span&gt;&lt;br/&gt;    MethodInfo[] methods = type.GetMethods();&lt;br/&gt;        &lt;br/&gt;    &lt;span class="rem"&gt;//打印方法签名和参数&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i=0; i &amp;lt; methods.Length; i++){&lt;br/&gt;    &lt;br/&gt;        Console.WriteLine (&lt;span class="str"&gt;"{0}"&lt;/span&gt;, methods[i]);&lt;br/&gt;        &lt;br/&gt;        ParameterInfo[] parameters = methods[i].GetParameters(); &lt;br/&gt;        &lt;br/&gt;        &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; j=0; j &amp;lt; parameters.Length; j++){   &lt;br/&gt;        Console.WriteLine (&lt;span class="str"&gt;" Parameter: {0} {1}"&lt;/span&gt;, parameters[j].ParameterType, parameters[j].Name);&lt;br/&gt;        }&lt;br/&gt;        &lt;br/&gt;    }&lt;span class="rem"&gt;//for (int i...) &lt;/span&gt;&lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;上面的代码可以看到C#的反射API略微优雅一点，C#提供了ParameterInfo包含方法的参数元数据，而Java提供的只是Class对象丢失了诸如参数名等信息。&lt;/p&gt;&lt;p&gt;有的时候需要获取指定类元数据对象，那么可以使用Java的java.lang.Class或C#的System.Type对象。要从类的实例获取元数据，在Java中可以使用getClass()方法而在C#中可以使用GetType()方法。如果要根据名字而不是创建一个类的实例来获取元数据可以这么做：&lt;/p&gt;C# Code&lt;br/&gt;  &lt;br/&gt;   Type t = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(ArrayList);&lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt;&lt;br/&gt;   Class c = java.util.Arraylist.&lt;span class="kwrd"&gt;class&lt;/span&gt;; &lt;span class="rem"&gt;/* 必须在类的完整名字后跟 .class */&lt;/span&gt;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;9、声明常量&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在Java中要声明常量可以使用final关键字。final的变量可以在编译时或运行时进行设置。在Java中，如果在基元上使用final的话基元的值不可变，如果在对象引用上使用final的话，则引用只可以指向一个对象。final的成员可以在声明的时候不初始化，但是必须要构造方法中初始化。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在C#中要声明常量使用const关键字来表示编译时常量，使用readonly关键字来表示运行时常量。基元常量和引用常量的语义对于C#和Java来说是一样的。&lt;/p&gt;&lt;p&gt;和C++不同的是，C#和Java不能通过语言结构来指定不可变的类。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;C# Code&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ConstantTest{&lt;br/&gt;    &lt;br/&gt;    &lt;span class="rem"&gt;/* 编译时常量*/&lt;/span&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; i1 = 10;   &lt;span class="rem"&gt;//隐含表示这是static的变量&lt;/span&gt;&lt;br/&gt;    &lt;br/&gt;    &lt;span class="rem"&gt;// 下面的代码不能通过编译&lt;/span&gt;&lt;br/&gt;    &lt;span class="rem"&gt;// public static const int i2 = 20; &lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* 运行时常量 */&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; &lt;span class="kwrd"&gt;uint&lt;/span&gt; l1 =  (&lt;span class="kwrd"&gt;uint&lt;/span&gt;) DateTime.Now.Ticks;&lt;br/&gt;  &lt;br/&gt;    &lt;span class="rem"&gt;/* 对象引用作为常量 */&lt;/span&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;readonly&lt;/span&gt; Object o = &lt;span class="kwrd"&gt;new&lt;/span&gt; Object();&lt;br/&gt; &lt;br/&gt;    &lt;span class="rem"&gt;/* 未初始化的只读变量 */&lt;/span&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;readonly&lt;/span&gt; &lt;span class="kwrd"&gt;float&lt;/span&gt; f; &lt;br/&gt;&lt;br/&gt;  &lt;br/&gt;    ConstantTest() {&lt;br/&gt;    &lt;span class="rem"&gt;// 未初始化的只读变量必须在构造方法中初始化&lt;/span&gt;&lt;br/&gt;    f = 17.21f; &lt;br/&gt;    }&lt;br/&gt;  &lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt;&lt;br/&gt;import java.util.*; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ConstantTest{&lt;br/&gt;    &lt;br/&gt;    &lt;span class="rem"&gt;/* Compile time constants */&lt;/span&gt; &lt;br/&gt;    final &lt;span class="kwrd"&gt;int&lt;/span&gt; i1 = 10;   &lt;span class="rem"&gt;//instance variable &lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; final &lt;span class="kwrd"&gt;int&lt;/span&gt; i2 = 20; &lt;span class="rem"&gt;//class variable &lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* run time constants */&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; final &lt;span class="kwrd"&gt;long&lt;/span&gt; l1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; Date().getTime();&lt;br/&gt;  &lt;br/&gt;    &lt;span class="rem"&gt;/* object reference as constant */&lt;/span&gt; &lt;br/&gt;    final Vector v = &lt;span class="kwrd"&gt;new&lt;/span&gt; Vector();&lt;br/&gt; &lt;br/&gt;    &lt;span class="rem"&gt;/* uninitialized final */&lt;/span&gt; &lt;br/&gt;    final &lt;span class="kwrd"&gt;float&lt;/span&gt; f; &lt;br/&gt;&lt;br/&gt;  &lt;br/&gt;    ConstantTest() {&lt;br/&gt;    &lt;span class="rem"&gt;// unitialized final variable must be initialized in constructor &lt;/span&gt;&lt;br/&gt;    f = 17.21f; &lt;br/&gt;    }&lt;br/&gt;  &lt;br/&gt;}&lt;p&gt;&lt;em&gt;注意：Java语言还支持方法上的final参数。在C#中没有这个功能。final参数只要用于允许传入方法的参数可以让方法内的内部类进行访问。&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;10、基元类型&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;对于Java中的每一个基元类型在C#中都有同名的对应（除了byte之外）。Java中的byte是有符号的，等价于C#中的sbyte，不同于C#的byte。C#还提供了一些基元类型的无符号版本，比如ulong、uint、ushort和byte。C#中最不同的基元类型是decimal类型，不会有舍入错误，当然也就需要更多空间也更慢。&lt;/p&gt;C# Code&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;decimal&lt;/span&gt; dec = 100.44m; &lt;span class="rem"&gt;//m is the suffix used to specify decimal numbers&lt;/span&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;double&lt;/span&gt;  dbl = 1.44e2d; //e &lt;span class="kwrd"&gt;is&lt;/span&gt; used to specify exponential notation &lt;span class="kwrd"&gt;while&lt;/span&gt; d &lt;span class="kwrd"&gt;is&lt;/span&gt; the suffix used &lt;span class="kwrd"&gt;for&lt;/span&gt; doubles&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;11、数组声明&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Java有两种方式声明数组。一种方式为了兼容C/C++的写法，另外一种更具有可读性，C#只能使用后者。&lt;/p&gt;C# Code&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;int&lt;/span&gt;[] iArray = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[100]; &lt;span class="rem"&gt;//valid, iArray is an object of type int[] &lt;/span&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;float&lt;/span&gt; fArray[] = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;float&lt;/span&gt;[100]; &lt;span class="rem"&gt;//ERROR: Won't compile  &lt;/span&gt;&lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;int&lt;/span&gt;[] iArray = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[100]; &lt;span class="rem"&gt;//valid, iArray is an object of type int[] &lt;/span&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;float&lt;/span&gt; fArray[] = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;float&lt;/span&gt;[100]; //valid, but isn't clear that fArray &lt;span class="kwrd"&gt;is&lt;/span&gt; an &lt;span class="kwrd"&gt;object&lt;/span&gt; of type &lt;span class="kwrd"&gt;float&lt;/span&gt;[] &lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;12、调用基类构造方法和构造方法链&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#和Java自动调用基类构造方法，并且提供了一种方式可以调用基类的有参构造方法。两种语言都要求派生类的构造方法在任何初始化之前先调用基类的构造方法防止使用没有初始化的成员。两种语言还提供了在一个构造方法中调用另一个构造方法的方式以减少构造方法中代码的重复。这种方式叫做构造方法链：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;C# Code&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; MyException: Exception&lt;br/&gt;{&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Id; &lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; MyException(&lt;span class="kwrd"&gt;string&lt;/span&gt; message): &lt;span class="kwrd"&gt;this&lt;/span&gt;(message, &lt;span class="kwrd"&gt;null&lt;/span&gt;, 100){ }&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; MyException(&lt;span class="kwrd"&gt;string&lt;/span&gt; message, Exception innerException): &lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;(message, innerException, 100){ }&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; MyException(&lt;span class="kwrd"&gt;string&lt;/span&gt; message, Exception innerException, &lt;span class="kwrd"&gt;int&lt;/span&gt; id):&lt;br/&gt;    &lt;span class="kwrd"&gt;base&lt;/span&gt;(message, innerException){&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.Id = id;   &lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;  &lt;br/&gt;Java Code&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; MyException extends Exception{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Id; &lt;br/&gt;    &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; MyException(String message){&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;(message, &lt;span class="kwrd"&gt;null&lt;/span&gt;, 100); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; MyException(String message, Exception innerException){&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;(message, innerException, 100); &lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; MyException( String message,Exception innerException, &lt;span class="kwrd"&gt;int&lt;/span&gt; id){&lt;br/&gt;      &lt;br/&gt;      super(message, innerException); &lt;br/&gt;      &lt;span class="kwrd"&gt;this&lt;/span&gt;.Id = id;     &lt;br/&gt;&lt;br/&gt;  }&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;13、可变长度参数列表&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在C和C++中可以指定函数接收一组参数。在printf和scanf类似的函数中大量使用这种特性。C#和Java允许我们定义一个参数接收可变数量的参数。在C#中可以在方法的最后一个参数上使用params关键字以及一个数组参数来实现，在Java中可以为类型名通过增加三个.来实现。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; ParamsTest{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PrintInts(&lt;span class="kwrd"&gt;string&lt;/span&gt; title, &lt;span class="kwrd"&gt;params&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    Console.WriteLine(title + &lt;span class="str"&gt;":"&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; num &lt;span class="kwrd"&gt;in&lt;/span&gt; args)&lt;br/&gt;        Console.WriteLine(num); &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    PrintInts(&lt;span class="str"&gt;"First Ten Numbers in Fibonacci Sequence"&lt;/span&gt;, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;Java Code&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PrintInts(String title, Integer... args){&lt;br/&gt;&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(title + &lt;span class="str"&gt;":"&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; num : args)&lt;br/&gt;        System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(num); &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args){&lt;br/&gt;&lt;br/&gt;    PrintInts(&lt;span class="str"&gt;"First Ten Numbers in Fibonacci Sequence"&lt;/span&gt;, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;14、泛型&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#和Java都提供了创建强类型数据结构且不需要在编译时知道具体类型的机制。在泛型机制出现以前，这个特性通过在数据结构中指定object类型并且在运行时转换成具体类型来实现。但是这种技术有许多缺点，包括缺乏类型安全、性能不佳以及代码膨胀。&lt;/p&gt;&lt;p&gt;如下代码演示了两种方式：&lt;/p&gt;# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Stack GetStackB4Generics(){&lt;br/&gt;    Stack s = &lt;span class="kwrd"&gt;new&lt;/span&gt; Stack(); &lt;br/&gt;    s.Push(2);&lt;br/&gt;    s.Push(4); &lt;br/&gt;    s.Push(5);&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; s;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Stack&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; GetStackAfterGenerics(){&lt;br/&gt;    Stack&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; s = &lt;span class="kwrd"&gt;new&lt;/span&gt; Stack&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt;(); &lt;br/&gt;    s.Push(12);&lt;br/&gt;    s.Push(14); &lt;br/&gt;    s.Push(50);&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; s;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(String[] args){&lt;br/&gt;&lt;br/&gt;    Stack s1 = GetStackB4Generics(); &lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; sum1 = 0; &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt;(s1.Count != 0){&lt;br/&gt;        sum1 += (&lt;span class="kwrd"&gt;int&lt;/span&gt;) s1.Pop(); &lt;span class="rem"&gt;//cast &lt;/span&gt;&lt;br/&gt;    }&lt;br/&gt;    &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Sum of stack 1 is "&lt;/span&gt; + sum1); &lt;br/&gt;&lt;br/&gt;    Stack&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; s2 = GetStackAfterGenerics(); &lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; sum2 = 0; &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt;(s2.Count != 0){&lt;br/&gt;        sum2 += s2.Pop(); &lt;span class="rem"&gt;//no cast&lt;/span&gt;&lt;br/&gt;    }&lt;br/&gt;    &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Sum of stack 2 is "&lt;/span&gt; + sum2); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}Java Code&lt;br/&gt;import java.util.*; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Stack GetStackB4Generics(){&lt;br/&gt;    Stack s = &lt;span class="kwrd"&gt;new&lt;/span&gt; Stack(); &lt;br/&gt;    s.push(2);&lt;br/&gt;    s.push(4); &lt;br/&gt;    s.push(5);&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; s;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Stack&amp;lt;Integer&amp;gt; GetStackAfterGenerics(){&lt;br/&gt;    Stack&amp;lt;Integer&amp;gt; s = &lt;span class="kwrd"&gt;new&lt;/span&gt; Stack&amp;lt;Integer&amp;gt;(); &lt;br/&gt;    s.push(12);&lt;br/&gt;    s.push(14); &lt;br/&gt;    s.push(50);&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; s;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args){&lt;br/&gt;&lt;br/&gt;    Stack s1 = GetStackB4Generics(); &lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; sum1 = 0; &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt;(!s1.empty()){&lt;br/&gt;        sum1 += (Integer) s1.pop(); &lt;span class="rem"&gt;//cast &lt;/span&gt;&lt;br/&gt;    }&lt;br/&gt;    &lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Sum of stack 1 is "&lt;/span&gt; + sum1); &lt;br/&gt;&lt;br/&gt;    Stack&amp;lt;Integer&amp;gt; s2 = GetStackAfterGenerics(); &lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; sum2 = 0; &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt;(!s2.empty()){&lt;br/&gt;        sum2 += s2.pop(); &lt;span class="rem"&gt;//no cast&lt;/span&gt;&lt;br/&gt;    }&lt;br/&gt;    &lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Sum of stack 2 is "&lt;/span&gt; + sum2); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;尽管和C++中的模板概念相似，C#和Java中的泛型特性实现上不一样。在Java中，泛型功能使用类型擦除来实现。泛型信息只是在编译的时候出现，编译后被编译器擦除所有类型声明替换为Object。编译器自动在核实的地方插入转换语句。这么做的原因是，泛型代码和不支持泛型的遗留代码可以互操作。类型擦除的泛型类型的主要问题是，泛型类型信息在运行时通过反射或运行时类型标识不可用。并且对于这种方式，泛型类型数据结构必须使用对象和非基元类型进行生命。所以只能有&lt;code&gt;Stack&amp;lt;Integer&amp;gt;而不是Stack&amp;lt;int&amp;gt;。&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;在C#中，.NET运行时中间语言IL直接支持泛型。泛型在编译的时候，生成的IL包含具体类型的占位符。在运行的时候，如果初始化一个泛型类型的引用，系统会看是否有人已经用过这个类型了，如果类型之前请求过则返回之前生成的具体类型，如果没有JIT编译器把泛型参数替换为IL中的具体类型然后再初始化新的类型。如果请求的类型是引用类型而不是值类型的话，泛型类型参数会替换为Object，但是不需要进行转换，因为.NET运行时会在访问的时候内部进行转换。&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;code&gt;在某些时候，我们的方法需要操作包含任意类型的数据结构而不是某个具体类型，但是又希望利用强类型泛型的优势。这个时候我们可以通过C#的泛型类型推断或Java通配类型实现。如下代码所示：&lt;/code&gt;&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//Prints the contents of any generic Stack by &lt;/span&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//using generic type inference &lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PrintStackContents&amp;lt;T&amp;gt;(Stack&amp;lt;T&amp;gt; s){&lt;br/&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt;(s.Count != 0){&lt;br/&gt;        Console.WriteLine(s.Pop()); &lt;br/&gt;    }    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(String[] args){&lt;br/&gt;&lt;br/&gt;    Stack&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; s2 = &lt;span class="kwrd"&gt;new&lt;/span&gt; Stack&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt;(); &lt;br/&gt;    s2.Push(4); &lt;br/&gt;    s2.Push(5); &lt;br/&gt;    s2.Push(6); &lt;br/&gt;&lt;br/&gt;    PrintStackContents(s2);     &lt;br/&gt;    &lt;br/&gt;    Stack&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; s1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; Stack&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(); &lt;br/&gt;    s1.Push(&lt;span class="str"&gt;"One"&lt;/span&gt;); &lt;br/&gt;    s1.Push(&lt;span class="str"&gt;"Two"&lt;/span&gt;); &lt;br/&gt;    s1.Push(&lt;span class="str"&gt;"Three"&lt;/span&gt;); &lt;br/&gt;&lt;br/&gt;    PrintStackContents(s1); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;Java Code&lt;br/&gt;import java.util.*; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//Prints the contents of any generic Stack by &lt;/span&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//specifying wildcard type &lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PrintStackContents(Stack&amp;lt;?&amp;gt; s){&lt;br/&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt;(!s.empty()){&lt;br/&gt;        System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(s.pop()); &lt;br/&gt;    }    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args){&lt;br/&gt;&lt;br/&gt;    Stack &amp;lt;Integer&amp;gt; s2 = &lt;span class="kwrd"&gt;new&lt;/span&gt; Stack &amp;lt;Integer&amp;gt;(); &lt;br/&gt;    s2.push(4); &lt;br/&gt;    s2.push(5); &lt;br/&gt;    s2.push(6); &lt;br/&gt;&lt;br/&gt;    PrintStackContents(s2);     &lt;br/&gt;    &lt;br/&gt;    Stack&amp;lt;String&amp;gt; s1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; Stack&amp;lt;String&amp;gt;(); &lt;br/&gt;    s1.push(&lt;span class="str"&gt;"One"&lt;/span&gt;); &lt;br/&gt;    s1.push(&lt;span class="str"&gt;"Two"&lt;/span&gt;); &lt;br/&gt;    s1.push(&lt;span class="str"&gt;"Three"&lt;/span&gt;); &lt;br/&gt;&lt;br/&gt;    PrintStackContents(s1); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&lt;code&gt;C#和Java都提供了泛型约束。对于C#有三种类型的约束：&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;1）派生约束，告诉编译器泛型类型参数需要从某个基类型继承，比如接口或基类&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;2）默认构造方法约束，告诉编译器泛型类型参数需要提供公共的默认构造方法&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;3）引用、值类型约束，泛型类型参数需要是引用类型或值类型&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;对于Java支持派生约束：&lt;/code&gt;&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Mammal {&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Mammal(){;}&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Speak(){;} &lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Cat : Mammal{&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Cat(){;}&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Speak(){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Meow"&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Dog : Mammal{&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Dog(){;}&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Speak(){&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Woof"&lt;/span&gt;);&lt;br/&gt;    } &lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MammalHelper&amp;lt;T&amp;gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; T: Mammal &lt;span class="rem"&gt;/* derivation constraint */&lt;/span&gt;,&lt;br/&gt;                                   &lt;span class="kwrd"&gt;new&lt;/span&gt;() &lt;span class="rem"&gt;/* default constructor constraint */&lt;/span&gt;{ &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; T CreatePet(){&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; T(); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; AnnoyNeighbors(Stack&amp;lt;T&amp;gt; pets){&lt;br/&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt;(pets.Count != 0){&lt;br/&gt;        Mammal m = pets.Pop(); &lt;br/&gt;        m.Speak();  &lt;br/&gt;    }    &lt;br/&gt;    }  &lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(String[] args){&lt;br/&gt;&lt;br/&gt;    Stack&amp;lt;Mammal&amp;gt; s2 = &lt;span class="kwrd"&gt;new&lt;/span&gt; Stack&amp;lt;Mammal&amp;gt;(); &lt;br/&gt;    s2.Push(MammalHelper&amp;lt;Dog&amp;gt;.CreatePet()); &lt;br/&gt;    s2.Push(MammalHelper&amp;lt;Cat&amp;gt;.CreatePet()); &lt;br/&gt;&lt;br/&gt;    MammalHelper&amp;lt;Mammal&amp;gt;.AnnoyNeighbors(s2);         &lt;br/&gt;    }&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;Java Code&lt;br/&gt;import java.util.*; &lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Mammal {&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; speak(); &lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Cat extends Mammal{&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; speak(){&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Meow"&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Dog extends Mammal{&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; speak(){&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Woof"&lt;/span&gt;);&lt;br/&gt;    } &lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;    &lt;br/&gt;    &lt;span class="rem"&gt;//derivation constraint applied to pets parameter&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; AnnoyNeighbors(Stack&amp;lt;? extends Mammal&amp;gt; pets){&lt;br/&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt;(!pets.empty()){&lt;br/&gt;        Mammal m = pets.pop(); &lt;br/&gt;        m.speak();  &lt;br/&gt;    }    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args){&lt;br/&gt;&lt;br/&gt;    Stack&amp;lt;Mammal&amp;gt; s2 = &lt;span class="kwrd"&gt;new&lt;/span&gt; Stack&amp;lt;Mammal&amp;gt;(); &lt;br/&gt;    s2.push(&lt;span class="kwrd"&gt;new&lt;/span&gt; Dog()); &lt;br/&gt;    s2.push(&lt;span class="kwrd"&gt;new&lt;/span&gt; Cat()); &lt;br/&gt;&lt;br/&gt;    AnnoyNeighbors(s2);         &lt;br/&gt;    }&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;C#还提供了default操作符可以返回类型的默认值。引用类型的默认值是null，值类型（比如int、枚举和结构）的默认值是0（0填充结构）。对于泛型default很有用，如下代码演示了这个操作符的作用：&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; T GetDefaultForType&amp;lt;T&amp;gt;(){&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;default&lt;/span&gt;(T); &lt;span class="rem"&gt;//return default value of type T&lt;/span&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(String[] args){&lt;br/&gt;    &lt;br/&gt;    Console.WriteLine(GetDefaultForType&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt;());&lt;br/&gt;    Console.WriteLine(GetDefaultForType&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;());    &lt;br/&gt;    Console.WriteLine(GetDefaultForType&amp;lt;&lt;span class="kwrd"&gt;float&lt;/span&gt;&amp;gt;());&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;输出：&lt;/p&gt;&lt;p&gt;0&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;0&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;15、for-each循环&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;for-each循环是很多脚本语言、编译工具、方法类库中非常常见的一种迭代结构。for-each循环简化了C#中实现System.Collections.IEnumerable接口或Java中java.lang.Iterable接口数组或类的迭代。&lt;/p&gt;&lt;p&gt;在C#中通过foreach关键字来创建for-each循环，而在Java中通过操作符:来实现。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt;[] greek_alphabet = {&lt;span class="str"&gt;"alpha"&lt;/span&gt;, &lt;span class="str"&gt;"beta"&lt;/span&gt;, &lt;span class="str"&gt;"gamma"&lt;/span&gt;, &lt;span class="str"&gt;"delta"&lt;/span&gt;, &lt;span class="str"&gt;"epsilon"&lt;/span&gt;};&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;foreach&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt; str &lt;span class="kwrd"&gt;in&lt;/span&gt; greek_alphabet)&lt;br/&gt;  Console.WriteLine(str + &lt;span class="str"&gt;" is a letter of the greek alphabet"&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt;String[] greek_alphabet = {&lt;span class="str"&gt;"alpha"&lt;/span&gt;, &lt;span class="str"&gt;"beta"&lt;/span&gt;, &lt;span class="str"&gt;"gamma"&lt;/span&gt;, &lt;span class="str"&gt;"delta"&lt;/span&gt;, &lt;span class="str"&gt;"epsilon"&lt;/span&gt;};&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;for&lt;/span&gt;(String str : greek_alphabet)&lt;br/&gt;  System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(str + &lt;span class="str"&gt;" is a letter of the greek alphabet"&lt;/span&gt;);&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;16、元数据注解&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;元数据注解提供了一种强大的方式来扩展编程语言和语言运行时的能力。注解是可以要求运行时进行一些额外任务、提供类额外信息扩展功能的一些指令。元数据注解在许多编程环境中很常见，比如微软的COM和linux内核。&lt;/p&gt;&lt;p&gt;C#特性提供了为模块、类型、方法或成员变量增加注解的方式。如下描述了一些.NET自带的特性以及如何使用它们来扩展C#的能力：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1）[MethodImpl(MethodImplOptions.Synchronized)] 用于指定多线程访问方法的时候使用锁进行保护，和Java的sychronized一样。&lt;/p&gt;&lt;p&gt;2）[Serializable]用于把类标记为可序列化的，和Java的实现Serializable接口相似。&lt;/p&gt;&lt;p&gt;3）[FlagsAttribute]用于指定枚举支持位操作。这样枚举就可以有多个值。&lt;/p&gt;C# Code&lt;br/&gt;   &lt;span class="rem"&gt;//declaration of bit field enumeration &lt;/span&gt;&lt;br/&gt;   [Flags]&lt;br/&gt;   &lt;span class="kwrd"&gt;enum&lt;/span&gt; ProgrammingLanguages{ &lt;br/&gt;   C     = 1, &lt;br/&gt;   Lisp  = 2, &lt;br/&gt;   Basic = 4, &lt;br/&gt;   All  = C | Lisp | Basic&lt;br/&gt;   }&lt;br/&gt;&lt;br/&gt;  aProgrammer.KnownLanguages  =  ProgrammingLanguages.Lisp; &lt;span class="rem"&gt;//set known languages  ="Lisp"&lt;/span&gt;&lt;br/&gt;  aProgrammer.KnownLanguages |=  ProgrammingLanguages.C; &lt;span class="rem"&gt;//set known languages  ="Lisp C"&lt;/span&gt;&lt;br/&gt;  aProgrammer.KnownLanguages &amp;amp;= ~ProgrammingLanguages.Lisp; &lt;span class="rem"&gt;//set known languages  ="C"&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;if&lt;/span&gt;((aProgrammer.KnownLanguages &amp;amp; ProgrammingLanguages.C) &amp;gt; 0){ &lt;span class="rem"&gt;//if programmer knows C&lt;/span&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//.. do something &lt;/span&gt;&lt;br/&gt;  }&lt;p&gt;4）[WebMethod]在ASP.NET中用于指定方法可以通过Web服务访问。&lt;/p&gt;&lt;p&gt;可以通过反射来访问模块、类、方法或字段的特性（详见&lt;a href="http://msdn.microsoft.com/zh-cn/library/system.attributetargets.aspx"&gt;http://msdn.microsoft.com/zh-cn/library/system.attributetargets.aspx&lt;/a&gt;）。对于运行时获取类是否支持某个行为特别有用，开发者可以通过继承System.Attribute类来创建他们自己的特性。如下是使用特性来提供类作者信息的例子，然后我们通过反射来读取这个信息。&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Reflection;&lt;br/&gt;[AttributeUsage(AttributeTargets.Class)]&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; AuthorInfoAttribute: System.Attribute{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; author; &lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; email; &lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; version;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; AuthorInfoAttribute(&lt;span class="kwrd"&gt;string&lt;/span&gt; author, &lt;span class="kwrd"&gt;string&lt;/span&gt; email){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.author = author; &lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.email  = email;&lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Version{&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    get{&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; version;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    set{&lt;br/&gt;        version = &lt;span class="kwrd"&gt;value&lt;/span&gt;; &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Email{&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    get{&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; email;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Author{&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    get{&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; author;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;[AuthorInfo(&lt;span class="str"&gt;"Dare Obasanjo"&lt;/span&gt;, &lt;span class="str"&gt;"kpako@yahoo.com"&lt;/span&gt;, Version=&lt;span class="str"&gt;"1.0"&lt;/span&gt;)]&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; HelloWorld{&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; AttributeTest{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* Get Type object of HelloWorld class */&lt;/span&gt;      &lt;br/&gt;    Type t = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(HelloWorld); &lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Author Information for "&lt;/span&gt; + t);&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"================================="&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt;(AuthorInfoAttribute att &lt;span class="kwrd"&gt;in&lt;/span&gt; t.GetCustomAttributes(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(AuthorInfoAttribute), &lt;span class="kwrd"&gt;false&lt;/span&gt;)){&lt;br/&gt;&lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;"Author: "&lt;/span&gt; + att.Author);&lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;"Email: "&lt;/span&gt; + att.Email);&lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;"Version: "&lt;/span&gt; + att.Version);   &lt;br/&gt;&lt;br/&gt;    }&lt;span class="rem"&gt;//foreach&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    }&lt;span class="rem"&gt;//Main&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Java的提供了为包、类型、方法、参数、成员或局部变量增加注解的能力。Java语言只内置了三种注解，如下：&lt;/p&gt;&lt;p&gt;1）@Override用于指定方法覆盖基类的方法。如果注解的方法并没有覆盖基类的方法，在编译的时候会出错。&lt;/p&gt;&lt;p&gt;2）@Deprecated用于指示某个方法已经废弃。使用废弃的方法会在编译的时候产生警告。&lt;/p&gt;&lt;p&gt;3）@SuppressWarnings用于防止编译器发出某个警告。这个注解可选接收参数来表明屏蔽哪种警告。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;和C#一样，可以通过反射来读取模块、类、方法或字段的注解。但是不同的是Java注解可以是元注解。开发者可以创建自定义的注解，创建方法和接口相似，只不过需要定义@interface关键字。如下是使用注解和通过反射读取信息的例子：&lt;/p&gt;Java Code&lt;br/&gt;import java.lang.annotation.*;&lt;br/&gt;import java.lang.reflect.*;&lt;br/&gt;&lt;br/&gt;@Documented &lt;span class="rem"&gt;//we want the annotation to show up in the Javadocs &lt;/span&gt;&lt;br/&gt;@Retention(RetentionPolicy.RUNTIME) &lt;span class="rem"&gt;//we want annotation metadata to be exposed at runtime&lt;/span&gt;&lt;br/&gt;@&lt;span class="kwrd"&gt;interface&lt;/span&gt; AuthorInfo{&lt;br/&gt;    String author(); &lt;br/&gt;    String email(); &lt;br/&gt;    String version() &lt;span class="kwrd"&gt;default&lt;/span&gt; &lt;span class="str"&gt;"1.0"&lt;/span&gt;;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;@AuthorInfo(author=&lt;span class="str"&gt;"Dare Obasanjo"&lt;/span&gt;, email=&lt;span class="str"&gt;"kpako@yahoo.com"&lt;/span&gt;)&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; HelloWorld{&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args) throws Exception{&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* Get Class object of HelloWorld class */&lt;/span&gt;      &lt;br/&gt;    Class c = Class.forName(&lt;span class="str"&gt;"HelloWorld"&lt;/span&gt;);&lt;br/&gt;    AuthorInfo a = (AuthorInfo) c.getAnnotation(AuthorInfo.&lt;span class="kwrd"&gt;class&lt;/span&gt;); &lt;br/&gt;    &lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Author Information for "&lt;/span&gt; + c);&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"======================================="&lt;/span&gt;);&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Author: "&lt;/span&gt; + a.author());&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Email: "&lt;/span&gt; + a.email());&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Version: "&lt;/span&gt; + a.version());      &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;17、枚举&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;枚举用于创建一组用于自定义的命名常量。尽管从表面上看C#和Java的枚举非常相同，但是在实现上它们完全不同。Java的枚举类型是纯种的类，也就是它们是类型安全并可以增加方法、字段或甚至实现接口进行扩展，而在C#中枚举纯粹是一个包装了数字类型（一般是int）的语法糖，并且不是类型安全的。如下代码演示了两者的区别：&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;enum&lt;/span&gt; DaysOfWeek{&lt;br/&gt;    SUNDAY, &lt;br/&gt;    MONDAY, &lt;br/&gt;    TUESDAY, &lt;br/&gt;    WEDNESDAY,&lt;br/&gt;    THURSDAY, &lt;br/&gt;    FRIDAY,&lt;br/&gt;    SATURDAY&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; isWeekDay(DaysOfWeek day){&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; !isWeekEnd(day);   &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; isWeekEnd(DaysOfWeek day){&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; (day == DaysOfWeek.SUNDAY || day == DaysOfWeek.SATURDAY); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(String[] args){&lt;br/&gt;&lt;br/&gt;    DaysOfWeek sun = DaysOfWeek.SUNDAY; &lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Is "&lt;/span&gt; + sun + &lt;span class="str"&gt;" a weekend? "&lt;/span&gt; + isWeekEnd(sun));&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Is "&lt;/span&gt; + sun + &lt;span class="str"&gt;" a week day? "&lt;/span&gt; + isWeekDay(sun));&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* Example of how C# enums are not type safe */&lt;/span&gt;&lt;br/&gt;    sun = (DaysOfWeek) 1999;&lt;br/&gt;    Console.WriteLine(sun);&lt;br/&gt;    &lt;br/&gt;    }&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;Java Code&lt;br/&gt;&lt;span class="kwrd"&gt;enum&lt;/span&gt; DaysOfWeek{&lt;br/&gt;    SUNDAY, &lt;br/&gt;    MONDAY, &lt;br/&gt;    TUESDAY, &lt;br/&gt;    WEDNESDAY,&lt;br/&gt;    THURSDAY, &lt;br/&gt;    FRIDAY,&lt;br/&gt;    SATURDAY;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; boolean isWeekDay(){&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; !isWeekEnd();   &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; boolean isWeekEnd(){&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt; == SUNDAY || &lt;span class="kwrd"&gt;this&lt;/span&gt; == SATURDAY); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args) throws Exception{&lt;br/&gt;&lt;br/&gt;    DaysOfWeek sun = DaysOfWeek.SUNDAY; &lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Is "&lt;/span&gt; + sun + &lt;span class="str"&gt;" a weekend? "&lt;/span&gt; + sun.isWeekEnd());&lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Is "&lt;/span&gt; + sun + &lt;span class="str"&gt;" a week day? "&lt;/span&gt; + sun.isWeekDay());&lt;br/&gt;    }&lt;br/&gt;}&lt;p&gt;运行结果：&lt;/p&gt;&lt;p&gt;Is SUNDAY a weekend? true &lt;br /&gt;Is SUNDAY a week day? false&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第三部分：C#中有，Java中也有但完全不同的地方&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1、嵌套类&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在Java和C#中可以在一个类中嵌套另一个。在Java中有两种类型的嵌套类，非静态的嵌套类也就是内部类，以及静态的嵌套类。Java的内部类可以认为是内部类和其包含类一对一的关系，每一个包含类的实例都保存了一个相应内部类的实例，内部类可以额访问包含类的成员变量以及包含非静态的方法。Java的静态内部类可以访问包含类的静态成员和方法。C#也有Java的静态嵌套类，但是没有Java的内部类。如下嵌套类声明是等价的：&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Car{&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; Engine engine;&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Engine{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; make; &lt;br/&gt;&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Car{&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; Engine engine;&lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Engine{&lt;br/&gt;&lt;br/&gt;    String make; &lt;br/&gt;&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&lt;em&gt;注意：在Java中，嵌套类可以在任何代码块中声明，包括方法，在C#中则不能。在方法中创建嵌套类看上去不必要，但是结合匿名内部类可以提供强大的设计模式。&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2、线程和易失成员&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;线程是程序内的顺序控制流程。程序或进程可以有多个线程并行执行，在执行任务的时候可以共享数据也可以独立运行。这样开发人员就可以在一个程序或进程中一次执行多个任务。线程的优点包括充分利用多处理器架构的资源、通过一边处理任务一边等待阻塞的系统调用（比如打印机或其它IO）减少执行时间，避免GUI应用程序失去响应。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Java线程可以通过继承java.lang.Thread并重写run()方法或者实现java.lang.Runable接口并实现run()方法来实现。在C#中，可以创建System.Threading.Thread对象并且传入System.Threading.Thread委托来表示需要线程运行的方法。在Java中，每一个类都从java.lang.Object继承wait()、notify()以及notify()。在C#中的等价是Thread.Threading.Montir类的Wait()、Pulse()以及PulseAll()。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Threading;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WorkerThread&lt;br/&gt;{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; idNumber;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; num_threads_made = 1;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; ThreadSample owner;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; WorkerThread(ThreadSample owner)&lt;br/&gt;    {&lt;br/&gt;&lt;br/&gt;        idNumber = num_threads_made;&lt;br/&gt;        num_threads_made++;&lt;br/&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.owner = owner;&lt;br/&gt;&lt;br/&gt;    }&lt;span class="rem"&gt;/* WorkerThread() */&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//sleeps for a random amount of time to simulate working on a task&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PerformTask()&lt;br/&gt;    {&lt;br/&gt;&lt;br/&gt;        Random r = &lt;span class="kwrd"&gt;new&lt;/span&gt; Random((&lt;span class="kwrd"&gt;int&lt;/span&gt;)DateTime.Now.Ticks);&lt;br/&gt;        &lt;span class="kwrd"&gt;int&lt;/span&gt; timeout = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)r.Next() % 1000;&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (timeout &amp;lt; 0)&lt;br/&gt;            timeout *= -1;&lt;br/&gt;&lt;br/&gt;        &lt;span class="rem"&gt;//Console.WriteLine(idNumber + ":A");&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br/&gt;        {&lt;br/&gt;            Thread.Sleep(timeout);&lt;br/&gt;        }&lt;br/&gt;        &lt;span class="kwrd"&gt;catch&lt;/span&gt; (ThreadInterruptedException e)&lt;br/&gt;        {&lt;br/&gt;            Console.WriteLine(&lt;span class="str"&gt;"Thread #"&lt;/span&gt; + idNumber + &lt;span class="str"&gt;" interrupted"&lt;/span&gt;);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;span class="rem"&gt;//Console.WriteLine(idNumber + ":B");&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;        owner.workCompleted(&lt;span class="kwrd"&gt;this&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    }&lt;span class="rem"&gt;/* performTask() */&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; getIDNumber() { &lt;span class="kwrd"&gt;return&lt;/span&gt; idNumber; }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;} &lt;span class="rem"&gt;// WorkerThread&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ThreadSample&lt;br/&gt;{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Mutex m = &lt;span class="kwrd"&gt;new&lt;/span&gt; Mutex();&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; ArrayList threadOrderList = &lt;span class="kwrd"&gt;new&lt;/span&gt; ArrayList();&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; NextInLine()&lt;br/&gt;    {&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt;)threadOrderList[0];&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; RemoveNextInLine()&lt;br/&gt;    {&lt;br/&gt;&lt;br/&gt;        threadOrderList.RemoveAt(0);&lt;br/&gt;&lt;br/&gt;        &lt;span class="rem"&gt;//all threads have shown up &lt;/span&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (threadOrderList.Count == 0)&lt;br/&gt;            Environment.Exit(0);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; workCompleted(WorkerThread worker)&lt;br/&gt;    {&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br/&gt;        {&lt;br/&gt;&lt;br/&gt;            &lt;span class="kwrd"&gt;lock&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;)&lt;br/&gt;            {&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;                &lt;span class="kwrd"&gt;while&lt;/span&gt; (worker.getIDNumber() != NextInLine())&lt;br/&gt;                {&lt;br/&gt;&lt;br/&gt;                    &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br/&gt;                    {&lt;br/&gt;                        &lt;span class="rem"&gt;//wait for some other thread to finish working&lt;/span&gt;&lt;br/&gt;                        Console.WriteLine(&lt;span class="str"&gt;"Thread #"&lt;/span&gt; + worker.getIDNumber() + &lt;span class="str"&gt;" is waiting for Thread #"&lt;/span&gt; +&lt;br/&gt;                                   NextInLine() + &lt;span class="str"&gt;" to show up."&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;                        Monitor.Wait(&lt;span class="kwrd"&gt;this&lt;/span&gt;, Timeout.Infinite);&lt;br/&gt;&lt;br/&gt;                    }&lt;br/&gt;                    &lt;span class="kwrd"&gt;catch&lt;/span&gt; (ThreadInterruptedException e) { }&lt;br/&gt;&lt;br/&gt;                }&lt;span class="rem"&gt;//while&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;                Console.WriteLine(&lt;span class="str"&gt;"Thread #"&lt;/span&gt; + worker.getIDNumber() + &lt;span class="str"&gt;" is home free"&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;                &lt;span class="rem"&gt;//remove this ID number from the list of threads yet to be seen&lt;/span&gt;&lt;br/&gt;                RemoveNextInLine();&lt;br/&gt;&lt;br/&gt;                &lt;span class="rem"&gt;//tell the other threads to resume&lt;/span&gt;&lt;br/&gt;                Monitor.PulseAll(&lt;span class="kwrd"&gt;this&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;        }&lt;br/&gt;        &lt;span class="kwrd"&gt;catch&lt;/span&gt; (SynchronizationLockException) { Console.WriteLine(&lt;span class="str"&gt;"SynchronizationLockException occurred"&lt;/span&gt;); }&lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(String[] args)&lt;br/&gt;    {&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;        ThreadSample ts = &lt;span class="kwrd"&gt;new&lt;/span&gt; ThreadSample();&lt;br/&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/* Launch 25 threads */&lt;/span&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 1; i &amp;lt;= 25; i++)&lt;br/&gt;        {&lt;br/&gt;            WorkerThread wt = &lt;span class="kwrd"&gt;new&lt;/span&gt; WorkerThread(ts);&lt;br/&gt;            ts.threadOrderList.Add(i);&lt;br/&gt;            Thread t = &lt;span class="kwrd"&gt;new&lt;/span&gt; Thread(&lt;span class="kwrd"&gt;new&lt;/span&gt; ThreadStart(wt.PerformTask));&lt;br/&gt;            t.Start();&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        Thread.Sleep(3600000); &lt;span class="rem"&gt;//wait for it all to end&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    }&lt;span class="rem"&gt;/* main(String[]) */&lt;/span&gt;&lt;br/&gt;}&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;Java Code&lt;br/&gt;import java.util.*; &lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; WorkerThread extends Thread{&lt;br/&gt;       &lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; Integer idNumber;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; num_threads_made = 1; &lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; ThreadSample owner; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; WorkerThread(ThreadSample owner){&lt;br/&gt;        &lt;br/&gt;        super(&lt;span class="str"&gt;"Thread #"&lt;/span&gt; + num_threads_made);   &lt;br/&gt;    &lt;br/&gt;        idNumber = &lt;span class="kwrd"&gt;new&lt;/span&gt; Integer(num_threads_made);   &lt;br/&gt;    num_threads_made++;        &lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.owner = owner;&lt;br/&gt;    &lt;br/&gt;    start(); &lt;span class="rem"&gt;//calls run and starts the thread.&lt;/span&gt;&lt;br/&gt;    }&lt;span class="rem"&gt;/* WorkerThread() */&lt;/span&gt;&lt;br/&gt;    &lt;br/&gt;    &lt;span class="rem"&gt;//sleeps for a random amount of time to simulate working on a task&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; run(){&lt;br/&gt;&lt;br/&gt;    Random r = &lt;span class="kwrd"&gt;new&lt;/span&gt; Random(System.currentTimeMillis()); &lt;br/&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; timeout = r.nextInt()  % 1000; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(timeout &amp;lt; 0)&lt;br/&gt;        timeout *= -1 ;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;try&lt;/span&gt;{        &lt;br/&gt;        Thread.sleep(timeout);      &lt;br/&gt;        } &lt;span class="kwrd"&gt;catch&lt;/span&gt; (InterruptedException e){&lt;br/&gt;            System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Thread #"&lt;/span&gt; + idNumber + &lt;span class="str"&gt;" interrupted"&lt;/span&gt;);&lt;br/&gt;        }&lt;br/&gt;    &lt;br/&gt;    owner.workCompleted(&lt;span class="kwrd"&gt;this&lt;/span&gt;); &lt;br/&gt;&lt;br/&gt;    }&lt;span class="rem"&gt;/* run() */&lt;/span&gt;&lt;br/&gt;    &lt;br/&gt;           &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Integer getIDNumber() {&lt;span class="kwrd"&gt;return&lt;/span&gt; idNumber;}&lt;br/&gt;         &lt;br/&gt;    &lt;br/&gt;} &lt;span class="rem"&gt;// WorkerThread&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ThreadSample{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; Vector threadOrderList = &lt;span class="kwrd"&gt;new&lt;/span&gt; Vector(); &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; Integer nextInLine(){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; (Integer) threadOrderList.firstElement(); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; removeNextInLine(){&lt;br/&gt;&lt;br/&gt;    threadOrderList.removeElementAt(0);&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//all threads have shown up &lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(threadOrderList.isEmpty())&lt;br/&gt;        System.exit(0); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; synchronized &lt;span class="kwrd"&gt;void&lt;/span&gt; workCompleted(WorkerThread worker){&lt;br/&gt;&lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt;(worker.getIDNumber().equals(nextInLine())==&lt;span class="kwrd"&gt;false&lt;/span&gt;){&lt;br/&gt;    &lt;br/&gt;        &lt;span class="kwrd"&gt;try&lt;/span&gt; {&lt;br/&gt;        &lt;span class="rem"&gt;//wait for some other thread to finish working&lt;/span&gt;&lt;br/&gt;        System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println (Thread.currentThread().getName() + &lt;span class="str"&gt;" is waiting for Thread #"&lt;/span&gt; + &lt;br/&gt;                    nextInLine() + &lt;span class="str"&gt;" to show up."&lt;/span&gt;);&lt;br/&gt;        wait();&lt;br/&gt;        } &lt;span class="kwrd"&gt;catch&lt;/span&gt; (InterruptedException e) {}&lt;br/&gt;           &lt;br/&gt;    }&lt;span class="rem"&gt;//while&lt;/span&gt;&lt;br/&gt;    &lt;br/&gt;    System.&lt;span class="kwrd"&gt;out&lt;/span&gt;.println(&lt;span class="str"&gt;"Thread #"&lt;/span&gt; + worker.getIDNumber() + &lt;span class="str"&gt;" is home free"&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//remove this ID number from the list of threads yet to be seen&lt;/span&gt;&lt;br/&gt;    removeNextInLine(); &lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;//tell the other threads to resume&lt;/span&gt;&lt;br/&gt;    notifyAll(); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; main(String[] args) throws InterruptedException{&lt;br/&gt;    &lt;br/&gt;&lt;br/&gt;    ThreadSample ts = &lt;span class="kwrd"&gt;new&lt;/span&gt; ThreadSample(); &lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/* Launch 25 threads */&lt;/span&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i=1; i &amp;lt;= 25; i++){&lt;br/&gt;        &lt;span class="kwrd"&gt;new&lt;/span&gt; WorkerThread(ts); &lt;br/&gt;        ts.threadOrderList.add(&lt;span class="kwrd"&gt;new&lt;/span&gt; Integer(i)); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    Thread.sleep(3600000); &lt;span class="rem"&gt;//wait for it all to end&lt;/span&gt;&lt;br/&gt;    &lt;br/&gt;    }&lt;span class="rem"&gt;/* main(String[]) */&lt;/span&gt; &lt;br/&gt;&lt;br/&gt;&lt;br/&gt;}//ThreadSample&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在许多情况下，我们不能确保代码执行的顺序和源代码一致。产生这种情况的原因包括编译器优化的时候重排语句顺序、或多处理器系统不能在全局内存中保存变量。要避免这个问题，C#和Javay引入了volatile关键字来告诉语言运行时不要重新调整字段的指令顺序。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;C# Code&lt;br/&gt;&lt;br/&gt;&lt;span class="rem"&gt;/* Used to lazily instantiate a singleton class */&lt;/span&gt; &lt;br/&gt;&lt;span class="rem"&gt;/*             WORKS AS EXPECTED                */&lt;/span&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;class&lt;/span&gt; Foo {&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;volatile&lt;/span&gt; Helper helper = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Helper getHelper() {&lt;br/&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (helper == &lt;span class="kwrd"&gt;null&lt;/span&gt;) {&lt;br/&gt;                &lt;span class="kwrd"&gt;lock&lt;/span&gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt;) {&lt;br/&gt;                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (helper == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br/&gt;                        helper = &lt;span class="kwrd"&gt;new&lt;/span&gt; Helper();&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; helper;&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;Java Code&lt;br/&gt;&lt;br/&gt;&lt;span class="rem"&gt;/* Used to lazily instantiate a singleton class */&lt;/span&gt; &lt;br/&gt;&lt;span class="rem"&gt;/* BROKEN UNDER CURRENT SEMANTICS FOR VOLATILE */&lt;/span&gt; &lt;br/&gt;&lt;br/&gt;  &lt;span class="kwrd"&gt;class&lt;/span&gt; Foo {&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;volatile&lt;/span&gt; Helper helper = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Helper getHelper() {&lt;br/&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (helper == &lt;span class="kwrd"&gt;null&lt;/span&gt;) {&lt;br/&gt;                synchronized(&lt;span class="kwrd"&gt;this&lt;/span&gt;) {&lt;br/&gt;                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (helper == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br/&gt;                        helper = &lt;span class="kwrd"&gt;new&lt;/span&gt; Helper();&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; helper;&lt;br/&gt;        }&lt;br/&gt;    }&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;尽管上面的代码除了lock和synchronized关键字之外没什么不同，Java的版本不保证在所有的JVM下都工作，详见&lt;a href="http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html"&gt;http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html&lt;/a&gt;。在C#中volatile的语义不会出现这样的问题，因为读写次序不能调整，同样被标记volatile的字段不会保存在寄存器中，对于多处理器系统确保变量保存在全局内存中。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;3、操作符重载&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;操作符重载允许特定的类或类型对于标准操作符具有新的语义。操作符重载可以用于简化某个常用操作的语法，比如Java中的字符串连接。操作符重载也是开发人员争议的一个地方，它在带来灵活性的同时也带来了滥用的危险。有些开发者会乱用重载（比如用++或--来表示连接或断开网络）或是让操作符不具有本来的意义（比如[]返回一个集合中某个索引项的复制而不是原始的对象）或重载了一半操作符（比如重载&amp;lt;但是不重载&amp;gt;）。&lt;/p&gt;&lt;p&gt;注意，和C++不用，C#不允许重载如下的操作符：new、()、||、&amp;amp;&amp;amp;、=或各种组合赋值，比如+=、-=。但是，重载的组合赋值会调用重载的操作符，比如+=会调用重载的+。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;C# Code&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; OverloadedNumber{&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; OverloadedNumber(&lt;span class="kwrd"&gt;int&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;){&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.&lt;span class="kwrd"&gt;value&lt;/span&gt; = &lt;span class="kwrd"&gt;value&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ToString(){&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;.ToString(); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; OverloadedNumber &lt;span class="kwrd"&gt;operator&lt;/span&gt; -(OverloadedNumber number){&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; OverloadedNumber(-number.&lt;span class="kwrd"&gt;value&lt;/span&gt;); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; OverloadedNumber &lt;span class="kwrd"&gt;operator&lt;/span&gt; +(OverloadedNumber number1, OverloadedNumber number2){&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; OverloadedNumber(number1.&lt;span class="kwrd"&gt;value&lt;/span&gt; + number2.&lt;span class="kwrd"&gt;value&lt;/span&gt;); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; OverloadedNumber &lt;span class="kwrd"&gt;operator&lt;/span&gt; ++(OverloadedNumber number){&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; OverloadedNumber(number.&lt;span class="kwrd"&gt;value&lt;/span&gt; + 1); &lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; OperatorOverloadingTest {&lt;br/&gt;&lt;br/&gt;  &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args){&lt;br/&gt;&lt;br/&gt;    OverloadedNumber number1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; OverloadedNumber(12); &lt;br/&gt;    OverloadedNumber number2 = &lt;span class="kwrd"&gt;new&lt;/span&gt; OverloadedNumber(125); &lt;br/&gt;&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Increment: {0}"&lt;/span&gt;, ++number1);&lt;br/&gt;    Console.WriteLine(&lt;span class="str"&gt;"Addition: {0}"&lt;/span&gt;, number1 + number2);&lt;br/&gt;  &lt;br/&gt;    }&lt;br/&gt;} &lt;span class="rem"&gt;// OperatorOverloadingTest&lt;/span&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201202/201202091757009103.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201202/201202091757003247.png" alt="image" width="238" height="96" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;4、switch语句&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#的switch和Java的switch有两个主要的区别。在C#中，switch语句支持字符串常量，除非标签不包含任何语句否则不允许贯穿。贯穿是显式禁止的，因为可能导致难以找到的bug。&lt;/p&gt;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;C# Code&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;switch&lt;/span&gt;(foo){    &lt;br/&gt;    &lt;br/&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;"A"&lt;/span&gt;: &lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;"A seen"&lt;/span&gt;);&lt;br/&gt;        &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;br/&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;"B"&lt;/span&gt;: &lt;br/&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;"C"&lt;/span&gt;: &lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;"B or C seen"&lt;/span&gt;);&lt;br/&gt;        &lt;span class="kwrd"&gt;break&lt;/span&gt;; &lt;br/&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/* ERROR: Won't compile due to fall-through at case "D" */&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;"D"&lt;/span&gt;: &lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;"D seen"&lt;/span&gt;);&lt;br/&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="str"&gt;"E"&lt;/span&gt;:&lt;br/&gt;        Console.WriteLine(&lt;span class="str"&gt;"E seen"&lt;/span&gt;);&lt;br/&gt;        &lt;span class="kwrd"&gt;break&lt;/span&gt;; &lt;br/&gt;    }&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201202/201202091757004120.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201202/201202091757018264.png" alt="image" width="602" height="51" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;5、程序集&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;C#程序集和Java的JAR文件有很多共性。程序集是.NET环境最基本的代码打包单元。程序集包含了中间语言代码、类的元数据以及其它执行任务所需要的数据。由于程序集是最基本的打包单元，和类型相关的一些行为必须在程序集级别进行。例如，安全授权、代码部署、程序集级别的版本控制。Java JAR文件有着相似的作用，但是实现不一样。程序集一般是EXE或DLL而JAR文件是ZIP文件格式的。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lovecindywang/aggbug/2344315.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lovecindywang/archive/2012/02/09/2344315.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lovecindywang/archive/2012/01/22/2328842.html</id><title type="text">一个小工具完成对memcached/kt/mongodb/redis的性能监测</title><summary type="text">虽然有很多开源工具通过插件或其它方式可以监测这些开源组件提供的内在性能（所谓内在性能就是这些开源组件提供的类STAT命令获取到的数据），但是不管是部署还是扩展都很麻烦，其实花1-2天时间完全可以实现一个这样的工具，并且扩展起来也很方便。比如mongodb的：又比如redis的：这个工具实现的功能如下：1）只需要简单配置（在DEMO代码里我硬编码了，您完全可以改为通过配置）就可以实现监控redis、mongodb、kt和memcached，之所以只有这些因为我们用到的只有这些，其实扩展一下也很方便，特别是有.NET客户端的组件。2）监控粒度可以选择，不同的监控粒度在一页上显示的时间段也不一样，大</summary><published>2012-01-22T12:38:00Z</published><updated>2012-01-22T12:38:00Z</updated><author><name>lovecindywang</name><uri>http://www.cnblogs.com/lovecindywang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lovecindywang/archive/2012/01/22/2328842.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lovecindywang/archive/2012/01/22/2328842.html"/><content type="html">&lt;p&gt;虽然有很多开源工具通过插件或其它方式可以监测这些开源组件提供的内在性能（所谓内在性能就是这些开源组件提供的类STAT命令获取到的数据），但是不管是部署还是扩展都很麻烦，其实花1-2天时间完全可以实现一个这样的工具，并且扩展起来也很方便。&lt;/p&gt;&lt;p&gt;比如mongodb的：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201201/201201222037229165.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201201/201201222037235379.png" alt="image" width="753" height="425" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201201/20120122203726131.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201201/201201222037285996.png" alt="image" width="758" height="428" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;又比如redis的：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201201/201201222037314238.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201201/201201222037347321.png" alt="image" width="768" height="434" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;这个工具实现的功能如下：&lt;/p&gt;&lt;p&gt;1）只需要简单配置（在DEMO代码里我硬编码了，您完全可以改为通过配置）就可以实现监控redis、mongodb、kt和memcached，之所以只有这些因为我们用到的只有这些，其实扩展一下也很方便，特别是有.NET客户端的组件。&lt;/p&gt;&lt;p&gt;2）监控粒度可以选择，不同的监控粒度在一页上显示的时间段也不一样，大致确保一页100个点左右。&lt;/p&gt;&lt;p&gt;3）为了简单，分页只是做了下拉，您完全可以修改为拖动或分页控件。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这个工具实现的原理如下：&lt;/p&gt;&lt;p&gt;1）利用mongodb保存大量数据，为了性能使用了mongodb的Capped集合，而且这样也无需考虑历史数据的移除。&lt;/p&gt;&lt;p&gt;2）10秒的监控粒度是原始收集数据的粒度，通过收集器定时收集数据，直接写入Mongodb。&lt;/p&gt;&lt;p&gt;3）其它监控粒度是基于原始数据的聚合，聚合器定时聚合数据，也是使用Capped集合，不过集合大小会小一点。&lt;/p&gt;&lt;p&gt;4）值的类型如下：&lt;/p&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;enum&lt;/span&gt; ItemValueType&lt;br/&gt;    {&lt;br/&gt;        TextValue,&lt;br/&gt;        StateValue,&lt;br/&gt;        TotalValue,&lt;br/&gt;        ExpressionValue,&lt;br/&gt;    }&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;对于StateValue也就是状态值直接存入数据库，对于TotalValue也就是总数值，会在内存中保存上一个值然后下一个值收集到之后会进行相减获取到差值，对于TextValue始终保存最新的值，对于ExpressionValue暂时没有做处理，您可以自己实现，对于Mongodb来说我们选择监测这些数据：&lt;/p&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, ComponentItem&amp;gt; items = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, ComponentItem&amp;gt;&lt;br/&gt;        { &lt;br/&gt;            { &lt;span class="str"&gt;"version"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"其它"&lt;/span&gt;, &lt;span class="str"&gt;"版本号"&lt;/span&gt;, ItemValueType.TextValue) },&lt;br/&gt;       &lt;br/&gt;            { &lt;span class="str"&gt;"mem.resident"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"内存"&lt;/span&gt;, &lt;span class="str"&gt;"使用的物理内存大小"&lt;/span&gt;, ItemValueType.StateValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"mem.virtual"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"内存"&lt;/span&gt;, &lt;span class="str"&gt;"使用的虚拟内存大小"&lt;/span&gt;, ItemValueType.StateValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"mem.mapped"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"内存"&lt;/span&gt;, &lt;span class="str"&gt;"映射的内存大小"&lt;/span&gt;, ItemValueType.StateValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"mem.mappedWithJournal"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"内存"&lt;/span&gt;, &lt;span class="str"&gt;"具有日志的映射的内存大小"&lt;/span&gt;, ItemValueType.StateValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"extra_info.page_faults"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"内存"&lt;/span&gt;, &lt;span class="str"&gt;"加载磁盘内容时发生页错误的次数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;&lt;br/&gt;            { &lt;span class="str"&gt;"connections.current"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"连接"&lt;/span&gt;, &lt;span class="str"&gt;"当前连接数"&lt;/span&gt;, ItemValueType.StateValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"connections.available"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"连接"&lt;/span&gt;, &lt;span class="str"&gt;"可用连接数"&lt;/span&gt;, ItemValueType.StateValue) },&lt;br/&gt;&lt;br/&gt;            { &lt;span class="str"&gt;"network.bytesIn"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"网络"&lt;/span&gt;, &lt;span class="str"&gt;"网络读取字节数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"network.bytesOut"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"网络"&lt;/span&gt;, &lt;span class="str"&gt;"网络发送字节数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"network.numRequests"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"网络"&lt;/span&gt;, &lt;span class="str"&gt;"网络请求数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;&lt;br/&gt;            { &lt;span class="str"&gt;"opcounters.insert"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"操作数"&lt;/span&gt;, &lt;span class="str"&gt;"insert数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"opcounters.query"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"操作数"&lt;/span&gt;, &lt;span class="str"&gt;"query数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"opcounters.update"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"操作数"&lt;/span&gt;, &lt;span class="str"&gt;"update数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"opcounters.delete"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"操作数"&lt;/span&gt;, &lt;span class="str"&gt;"delete数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"opcounters.getmore"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"操作数"&lt;/span&gt;, &lt;span class="str"&gt;"游标getmore数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"opcounters.command"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"操作数"&lt;/span&gt;, &lt;span class="str"&gt;"其它操作数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;&lt;br/&gt;            { &lt;span class="str"&gt;"indexCounters.btree.accesses"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"索引"&lt;/span&gt;, &lt;span class="str"&gt;"访问索引次数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"indexCounters.btree.hits"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"索引"&lt;/span&gt;, &lt;span class="str"&gt;"内存命中索引次数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"indexCounters.btree.misses"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"索引"&lt;/span&gt;, &lt;span class="str"&gt;"内存不命中索引次数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"indexCounters.btree.resets"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"索引"&lt;/span&gt;, &lt;span class="str"&gt;"索引计数器重置次数"&lt;/span&gt;, ItemValueType.TotalValue) },&lt;br/&gt;            { &lt;span class="str"&gt;"indexCounters.btree.hits * 100 / indexCounters.btree.accesses"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ComponentItem(&lt;span class="str"&gt;"索引"&lt;/span&gt;, &lt;span class="str"&gt;"hitsratio "&lt;/span&gt;, ItemValueType.ExpressionValue) },&lt;br/&gt;        };&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;5）客户端很简单，使用了highchart+ajax，直接和wcf的服务端交互获取jsonp数据源。&lt;/p&gt;  &amp;lt;system.serviceModel&amp;gt;&lt;br/&gt;    &amp;lt;behaviors&amp;gt;&lt;br/&gt;      &amp;lt;serviceBehaviors&amp;gt;&lt;br/&gt;        &amp;lt;behavior name=&lt;span class="str"&gt;"ServiceBehaviour"&lt;/span&gt; &amp;gt;&lt;br/&gt;          &amp;lt;serviceDebug includeExceptionDetailInFaults=&lt;span class="str"&gt;"true"&lt;/span&gt;/&amp;gt;&lt;br/&gt;          &amp;lt;serviceMetadata /&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;/behavior&amp;gt;&lt;br/&gt;      &amp;lt;/serviceBehaviors&amp;gt;&lt;br/&gt;      &amp;lt;endpointBehaviors&amp;gt;&lt;br/&gt;        &amp;lt;behavior name=&lt;span class="str"&gt;"HttpBehaviour"&lt;/span&gt;&amp;gt;&lt;br/&gt;          &amp;lt;webHttp defaultBodyStyle=&lt;span class="str"&gt;"Wrapped"&lt;/span&gt; defaultOutgoingResponseFormat=&lt;span class="str"&gt;"Json"&lt;/span&gt; helpEnabled=&lt;span class="str"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br/&gt;          &amp;lt;enableWebScript /&amp;gt;&lt;br/&gt;        &amp;lt;/behavior&amp;gt;&lt;br/&gt;      &amp;lt;/endpointBehaviors&amp;gt;&lt;br/&gt;    &amp;lt;/behaviors&amp;gt;&lt;br/&gt;    &amp;lt;bindings&amp;gt;&lt;br/&gt;      &amp;lt;webHttpBinding&amp;gt;&lt;br/&gt;        &amp;lt;binding name=&lt;span class="str"&gt;"webHttpBindingJsonP"&lt;/span&gt; crossDomainScriptAccessEnabled=&lt;span class="str"&gt;"true"&lt;/span&gt;/&amp;gt;&lt;br/&gt;      &amp;lt;/webHttpBinding&amp;gt;&lt;br/&gt;    &amp;lt;/bindings&amp;gt;&lt;br/&gt;    &amp;lt;services&amp;gt;&lt;br/&gt;      &amp;lt;service name=&lt;span class="str"&gt;"Adhesive.ComponentPerformance.Core.Service"&lt;/span&gt; behaviorConfiguration=&lt;span class="str"&gt;"ServiceBehaviour"&lt;/span&gt; &amp;gt;&lt;br/&gt;        &amp;lt;endpoint address=&lt;span class="str"&gt;"http://localhost:8888/"&lt;/span&gt;&lt;br/&gt;                   binding=&lt;span class="str"&gt;"webHttpBinding"&lt;/span&gt; bindingConfiguration=&lt;span class="str"&gt;"webHttpBindingJsonP"&lt;/span&gt;&lt;br/&gt;                  behaviorConfiguration=&lt;span class="str"&gt;"HttpBehaviour"&lt;/span&gt;&lt;br/&gt;                  contract=&lt;span class="str"&gt;"Adhesive.ComponentPerformance.Core.Service"&lt;/span&gt; /&amp;gt;&lt;br/&gt;        &amp;lt;endpoint address=&lt;span class="str"&gt;"http://localhost:8888/mex"&lt;/span&gt; binding=&lt;span class="str"&gt;"mexHttpBinding"&lt;/span&gt; contract=&lt;span class="str"&gt;"IMetadataExchange"&lt;/span&gt;/&amp;gt;&lt;br/&gt;&lt;br/&gt;      &amp;lt;/service&amp;gt;&lt;br/&gt;    &amp;lt;/services&amp;gt;&lt;br/&gt;  &amp;lt;/system.serviceModel&amp;gt;&lt;p&gt;话不多说，&lt;a href="http://files.cnblogs.com/lovecindywang/%E5%88%86%E5%B8%83%E5%BC%8F%E6%9C%8D%E5%8A%A1%E7%8A%B6%E6%80%81%E7%9B%91%E6%B5%8B.zip"&gt;点击这里&lt;/a&gt;下载DEMO代码，在使用前建议你修改如下地方：&lt;/p&gt;&lt;p&gt;1）完善记录日志的地方&lt;/p&gt;&lt;p&gt;2）把配置改为你自己的配置服务&lt;/p&gt;&lt;p&gt;3）完善其它需要监测的开源组件&lt;/p&gt;&lt;p&gt;4）完善网站的分页等功能&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;最后预祝大家新年快乐！&lt;/p&gt;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;img src="http://www.cnblogs.com/lovecindywang/aggbug/2328842.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lovecindywang/archive/2012/01/22/2328842.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lovecindywang/archive/2012/01/11/2318973.html</id><title type="text">框架规划</title><summary type="text">一个比较成规模的系统，很多东西依赖官方组件不能满足定制、灵活、性能、监控的要求，需要开发哪些东西？略微整理了一下，这也是我们的目标。宗旨：1）自己的组件需要处处体现集中配置、集中日志、内置性能监视器、集中监控、自动部署等理念！2）考虑分期，先实现必要的东西，尽量轻量化，微软搞的东西很容易太重！3）尽量考虑不依赖硬件的横向扩展！4）分布式分布式说白了很多时候是对用户来说是集中的单点的，在后端是分布式的用于承载大量数据和大量请求！5）分布式要解决的问题？同步、路由、负载均衡、可用性检测、数据迁移、性能、治理。。。</summary><published>2012-01-11T03:13:00Z</published><updated>2012-01-11T03:13:00Z</updated><author><name>lovecindywang</name><uri>http://www.cnblogs.com/lovecindywang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lovecindywang/archive/2012/01/11/2318973.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lovecindywang/archive/2012/01/11/2318973.html"/><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一个比较成规模的系统，很多东西依赖官方组件不能满足定制、灵活、性能、监控的要求，需要开发哪些东西？略微整理了一下，这也是我们的目标。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/103060/2012011115085922.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;宗旨：&lt;/p&gt;&lt;p&gt;1）自己的组件需要处处体现集中配置、集中日志、内置性能监视器、集中监控、自动部署等理念！&lt;/p&gt;&lt;p&gt;2）考虑分期，先实现必要的东西，尽量轻量化，微软搞的东西很容易太重！&lt;/p&gt;&lt;p&gt;3）尽量考虑不依赖硬件的横向扩展！&lt;/p&gt;&lt;p&gt;4）分布式分布式说白了很多时候是对用户来说是集中的单点的，在后端是分布式的用于承载大量数据和大量请求！&lt;/p&gt;&lt;p&gt;5）分布式要解决的问题？同步、路由、负载均衡、可用性检测、数据迁移、性能、治理。。。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lovecindywang/aggbug/2318973.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lovecindywang/archive/2012/01/11/2318973.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lovecindywang/archive/2011/12/16/2290511.html</id><title type="text">Adhesive问答之Mongodb数据服务</title><summary type="text">Q：Mongodb数据服务有什么用？ A：首先，Mongodb适合保存大量的非业务数据，因此，Adhesive框架提倡把不是非常重要的非业务数据（比如应用程序信息中心的日志、异常、状态数据，又比如WCF扩展模块的WCF调用数据，或者其它的各种业务日志、监控日志）保存在Mongodb中。虽然Mongodb的非结构化模式适合保存各种类型的数据，但是我们不得不针对各种类型的数据进行重复开发来解决一些问...</summary><published>2011-12-16T09:42:00Z</published><updated>2011-12-16T09:42:00Z</updated><author><name>lovecindywang</name><uri>http://www.cnblogs.com/lovecindywang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lovecindywang/archive/2011/12/16/2290511.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lovecindywang/archive/2011/12/16/2290511.html"/><content type="html">&lt;p&gt;Q：Mongodb数据服务有什么用？&lt;/p&gt;  &lt;p&gt;A：首先，Mongodb适合保存大量的非业务数据，因此，Adhesive框架提倡把不是非常重要的非业务数据（比如应用程序信息中心的日志、异常、状态数据，又比如WCF扩展模块的WCF调用数据，或者其它的各种业务日志、监控日志）保存在Mongodb中。虽然Mongodb的非结构化模式适合保存各种类型的数据，但是我们不得不针对各种类型的数据进行重复开发来解决一些问题：&lt;/p&gt;  &lt;p&gt;1）往往大量的数据希望是后台队列异步提交的，并且还需要容忍服务端和数据库的短时间不可用，因此需要开发一套客户端和服务端的双队列。&lt;/p&gt;  &lt;p&gt;2）在数据保存到数据库的时候需要考虑分表和分库，数据保存后需要考虑索引的建立、历史数据的删除。&lt;/p&gt;  &lt;p&gt;3）最重要的是，数据不是保存就了事了，我们还需要针对不同的数据开发一套后台，涉及到权限、各种方式的浏览。&lt;/p&gt;  &lt;p&gt;在以前，我们针对每一个业务都需要进行短则一周，长则一个月的开发，开发一套客户端收集数据的程序、开发一套服务端提交数据的程序、再开发一套后台程序。&lt;/p&gt;  &lt;p&gt;而现在，Mongodb数据服务负责搞定这所有的一切，可以这么说，如果希望把自定义的任何数据通过Mongodb数据服务保存到Mongodb中去的话，您只需要&lt;/p&gt;  &lt;p&gt;1）花10分钟左右来涉及自定义类，并且为属性应用一些特性来告诉Mongodb数据服务如何保存和呈现这些数据。&lt;/p&gt;  &lt;p&gt;2）花5分钟左右来配置权限、客户端、服务端等等。&lt;/p&gt;  &lt;p&gt;3）花10秒的时间，调用一行语句进行入库。&lt;/p&gt;  &lt;p&gt;不管是什么程序日志、业务日志，不到20分钟时间的开发，您就可以在Mongdb数据服务的后台以各种方式看到数据。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Q：Mongodb数据服务的亮点在哪里？&lt;/p&gt;  &lt;p&gt;A：除了上面说的，可以节省开发时间之外，其它亮点如下：&lt;/p&gt;  &lt;p&gt;1）可以进行简单的配置来完成相对比较复杂的组合查询，比如要实现类型这样的搜索：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741473265.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741473821.png" width="593" height="105" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;只需要定义元数据即可：&lt;/p&gt;          [MongodbPersistenceItem(MongodbIndexOption = MongodbIndexOption.Ascending)]&lt;br/&gt;        [MongodbPresentationItem(DisplayName = &lt;span class="str"&gt;&amp;quot;借书者&amp;quot;&lt;/span&gt;,  ShowInTableView = &lt;span class="kwrd"&gt;true&lt;/span&gt;, MongodbFilterOption = MongodbFilterOption.TextBoxFilter)]&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; UserName { get; set; }&lt;br/&gt;&lt;br/&gt;        [MongodbPersistenceItem(MongodbIndexOption = MongodbIndexOption.Ascending)]&lt;br/&gt;        [MongodbPresentationItem(DisplayName = &lt;span class="str"&gt;&amp;quot;状态变化&amp;quot;&lt;/span&gt;, ShowInTableView = &lt;span class="kwrd"&gt;true&lt;/span&gt;, MongodbFilterOption = MongodbFilterOption.DropDownListFilter)]&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Status Status { get; set; }&lt;br/&gt;&lt;br/&gt;        [MongodbPersistenceItem(MongodbIndexOption = MongodbIndexOption.Ascending)]&lt;br/&gt;        [MongodbPresentationItem(DisplayName = &lt;span class="str"&gt;&amp;quot;书籍分类&amp;quot;&lt;/span&gt;, ShowInTableView = &lt;span class="kwrd"&gt;true&lt;/span&gt;, MongodbFilterOption = MongodbFilterOption.CheckBoxListFilter)]&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Category { get; set; }&lt;p&gt;又比如我们希望记录一个操作日志：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741487202.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741487758.png" width="460" height="232" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;元数据定义如下：&lt;/p&gt;        [MongodbPersistenceItem(ColumnName = &lt;span class="str"&gt;&amp;quot;A&amp;quot;&lt;/span&gt;, MongodbIndexOption = MongodbIndexOption.Ascending)]&lt;br/&gt;        [MongodbPresentationItem(DisplayName = &lt;span class="str"&gt;&amp;quot;行为&amp;quot;&lt;/span&gt;, ShowInTableView = &lt;span class="kwrd"&gt;true&lt;/span&gt;, MongodbFilterOption = MongodbFilterOption.DropDownListFilter)]&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Action { get; set; }&lt;br/&gt;&lt;br/&gt;        [MongodbPersistenceItem(ColumnName = &lt;span class="str"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;, MongodbIndexOption = MongodbIndexOption.Ascending)]&lt;br/&gt;        [MongodbPresentationItem(DisplayName = &lt;span class="str"&gt;&amp;quot;分类&amp;quot;&lt;/span&gt;, ShowInTableView = &lt;span class="kwrd"&gt;true&lt;/span&gt;, MongodbCascadeFilterOption = MongodbCascadeFilterOption.LevelOne)]&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; CategoryName { get; set; }&lt;br/&gt;&lt;br/&gt;        [MongodbPersistenceItem(ColumnName = &lt;span class="str"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, MongodbIndexOption = MongodbIndexOption.Ascending)]&lt;br/&gt;        [MongodbPresentationItem(DisplayName = &lt;span class="str"&gt;&amp;quot;数据库&amp;quot;&lt;/span&gt;, ShowInTableView = &lt;span class="kwrd"&gt;true&lt;/span&gt;, MongodbCascadeFilterOption = MongodbCascadeFilterOption.LevelTwo)]&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; DatabaseName { get; set; }&lt;br/&gt;&lt;br/&gt;        [MongodbPersistenceItem(ColumnName = &lt;span class="str"&gt;&amp;quot;TN&amp;quot;&lt;/span&gt;, MongodbIndexOption = MongodbIndexOption.Ascending)]&lt;br/&gt;        [MongodbPresentationItem(DisplayName = &lt;span class="str"&gt;&amp;quot;表&amp;quot;&lt;/span&gt;, ShowInTableView = &lt;span class="kwrd"&gt;true&lt;/span&gt;, MongodbCascadeFilterOption = MongodbCascadeFilterOption.LevelThree)]&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; TableName { get; set; }&lt;p&gt;这里可以看到，在后台不但呈现出了这些搜索控件，并且也填充了内容。由于考虑到性能，这些Distinct的数据不是通过Mongodb的Distinct功能完成的，而是在插入数据的时候统计这些数据，定时双向同步到Mongodb中的元数据表：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741488314.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741485283.png" width="386" height="421" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;2）丰富的查询方式：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741485839.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741488347.png" width="570" height="91" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;列表：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161745539883.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161745545522.png" width="948" height="460" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;数据量统计：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741504401.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741505514.png" width="896" height="431" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;分组统计：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741513072.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741513138.png" width="910" height="276" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;详细：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741511742.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741522680.png" width="946" height="471" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;不管是希望看列表、看数据量统计、看数据分组统计还是详细数据都可以满足要求，不许开发一行代码。&lt;/p&gt;&lt;p&gt;3）系统自己会处理分表、分库、过期数据、索引、缓存、队列等等。。。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Q：Mongodb数据服务的应用范围在哪里？&lt;/p&gt;&lt;p&gt;A：一般Mongodb适合保存非业务数据，由于Mongodb数据服务模块使用的是客户端和服务端的双队列，因此即使数据量再大也不会影响正常业务的进行，但数据可能会在服务不可用并且队列满的时候丢失。因此保存程序日志、业务日志、操作日志、监控数据、异常信息、反馈信息等等数据非常适合。需要说明的是，Adhesive框架的应用程序信息中心模块以及WCF分布式服务模块的所有日志都采用Mongodb数据服务进行保存。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Q：如何自定义对象以及使用Mongodb数据服务？&lt;/p&gt;&lt;p&gt;A：参见文章&lt;a title="http://www.cnblogs.com/lovecindywang/archive/2011/10/28/2227808.html" href="http://www.cnblogs.com/lovecindywang/archive/2011/10/28/2227808.html"&gt;http://www.cnblogs.com/lovecindywang/archive/2011/10/28/2227808.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Q：在自定义对象上配置的元数据改动了会怎么样？&lt;/p&gt;&lt;p&gt;A：从客户端方面来说每一种类型的元数据元数据会随着第一条数据提交到服务端，并且只会提交一次，因此如果你改了元数据，肯定是需要重新启动系统的，在启动后新的元数据会保存到数据库中，从服务端方面来说，元数据不会每次都从数据库获取，只是在“维护”的时候同步一次，默认的维护时间是1分钟，因此元数据修改后1分钟后可以在后台看到效果。&lt;/p&gt;&lt;p&gt;1）如果删除了列，那么列的元数据也会丢失，在后台可能就不会看到这个列了，但是老的数据不会丢失。&lt;/p&gt;&lt;p&gt;2）如果增加了以及列的元数据，那么相关列的值对于老的数据可能就是空，只会在新数据出现新的列。&lt;/p&gt;&lt;p&gt;3）如果要对既有列修改元数据的话，不能修改MongodbPersistenceItem的ColumnName也就是数据库中的列名，否则老的数据都会显示不出来。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Q：Mongodb数据服务的结构是怎么样的？&lt;/p&gt;&lt;p&gt;A：Mongodb数据服务写入数据的流程如下：插入数据到客户端队列-客户端队列取出数据提取元数据进行数据重组-客户端队列通过WCF分布式服务模块提交数据到服务端队列-服务端队列-服务端队列取出数据进行索引项更新-服务端队列把数据提交到数据库&lt;/p&gt;&lt;p&gt;Mongodb数据服务读取数据的流程如下：通过WCF分布式服务模块连接服务端读取数据-服务端从数据库取出实际的数据-服务端从内存中获取元数据-服务端把实际数据和元数据进行合并并返回客户端&lt;/p&gt;&lt;p&gt;Mongodb数据服务的服务端有一个很重要的维护服务，它的工作如下：&lt;/p&gt;&lt;p&gt;1）同步元数据&lt;/p&gt;&lt;p&gt;2）同步列的索引数据（比如高级数据筛选下拉框和多选框的内容）&lt;/p&gt;&lt;p&gt;3）清空历史数据（如果设置了过期天数的话）&lt;/p&gt;&lt;p&gt;4）从数据库获取数据库服务器、数据库、表、索引四个层次的实际状态&lt;/p&gt;&lt;p&gt;5）建立索引&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Q：Mongodb数据服务的配置需要注意哪些地方？&lt;/p&gt;&lt;p&gt;A：注意点如下：&lt;/p&gt;&lt;p&gt;1）在新定义自定义类型之后需要在配置服务中配置数据项，否则数据无法提交到服务端也无法提交到数据库&lt;/p&gt;&lt;p&gt;2）定义在列上的特性注意冲突和一些约束，尽量&lt;/p&gt;&lt;p&gt;3）适当清空下修改默认的参数（比如队列提交批次、最大数据条数）来改善性能&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Q：Mongodb数据服务需要怎么配置Mongodb？&lt;/p&gt;&lt;p&gt;A：我们的每一个类型可以配置不同的服务器集群，因此在一定程度上可以实现方便的扩容：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741522157.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741524350.png" width="563" height="183" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;考虑到分担压力，系统默认支持读（后台查询）写（提交数据以及维护）分离，因此可以配置MASTER-SALVE的Mongodb&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741526858.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741538286.png" width="675" height="135" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;需要注意的是，在理论情况下，后台进行的所有操作都不会进行表扫描，在索引未创建完成的情况下，是不会出现相关的搜索控件的，因此可以配置Mongodb为不允许表扫描：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741537207.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201112/201112161741531351.png" width="1207" height="29" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Q：Mongodb数据服务可以使用老的Mongodb集群吗？&lt;/p&gt;&lt;p&gt;A：可以，Mongodb数据服务通过Metadata数据库来知道哪些是自己的数据库，其它数据库不会去管理，后台也看不到。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lovecindywang/aggbug/2290511.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lovecindywang/archive/2011/12/16/2290511.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lovecindywang/archive/2011/11/28/2265862.html</id><title type="text">Adhesive框架系列文章--报警处理流程使用实践</title><summary type="text">框架除了报警之外还提供了简单的报警处理流程。 先来看一下报警相关的配置： 比如这里有一个报警，30秒检查一次30秒内相关数据如果超过10条则报警。 在报警后，系统会自动创建一个事件，相关人员登录到后台可以看到这个事件并进行处理，如果事件在处理了，那么报警会暂停，一直到处理完成之后重新开启。 当然，如果管理员一直没有结束某个事件，系统会自动关闭过期事件，也就是这里的5分钟（Process...</summary><published>2011-11-28T02:32:00Z</published><updated>2011-11-28T02:32:00Z</updated><author><name>lovecindywang</name><uri>http://www.cnblogs.com/lovecindywang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lovecindywang/archive/2011/11/28/2265862.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lovecindywang/archive/2011/11/28/2265862.html"/><content type="html">&lt;p&gt;框架除了报警之外还提供了简单的报警处理流程。&lt;/p&gt;  &lt;p&gt;先来看一下报警相关的配置：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/20111128103220481.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032214036.png" width="873" height="236" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;比如这里有一个报警，30秒检查一次30秒内相关数据如果超过10条则报警。&lt;/p&gt;  &lt;p&gt;在报警后，系统会自动创建一个事件，相关人员登录到后台可以看到这个事件并进行处理，如果事件在处理了，那么报警会暂停，一直到处理完成之后重新开启。&lt;/p&gt;  &lt;p&gt;当然，如果管理员一直没有结束某个事件，系统会自动关闭过期事件，也就是这里的5分钟（ProcessTimeout）。&lt;/p&gt;  &lt;p&gt;假设，我们添加10条数据，然后可以在报警界面看到这个事件：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032216827.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032229269.png" width="865" height="205" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;点击详情：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032223937.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032229793.png" width="1001" height="191" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;在这里可以输入事件的初步结论，注意短消息和邮件消息的字数限制，比如：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032226413.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032223348.png" width="968" height="237" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;接手表示开始处理事件，完成表示直接关闭事件。如果这个事件需要一定时间解决，可以点击接手，如果这是一个偶然的报警，并且不需要处理，可以直接点击关闭。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032228331.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032221679.png" width="962" height="180" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;点击接手后收到邮件，并且可以在处理中事件列表中发现这个事件：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032238298.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032233282.png" width="951" height="189" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;在这里可以看到之前的处理经过，并且还可以继续由他人处理这个事件，当然也可以关闭事件。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032235724.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032238199.png" width="843" height="287" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;比如我们填写一些信息，然后点击完成：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032249595.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032249038.png" width="883" height="323" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;在这里，我们测试一下超时关闭，如果超过5分钟没有结束事件，事件会被系统关闭：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032245658.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111281032246497.png" width="989" height="123" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;好了，整个流程基本介绍完了，这个流程虽然简单但实用，通过这个平台，大家都可以知道各种事件的处理过程。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lovecindywang/aggbug/2265862.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lovecindywang/archive/2011/11/28/2265862.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lovecindywang/archive/2011/11/09/2242337.html</id><title type="text">在Silverlight程序中使用Thread一个很容易被忽略的问题</title><summary type="text">有一个很常见的功能，我们需要在一个子窗口中定时调用服务，然后更新控件的内容，只要窗口开着就一直会调用服务。 那么现在就来完成这个功能，首先定义一个服务： public class Service1 : IService1 { public string DoWork(string name) { File.AppendAllTex...</summary><published>2011-11-09T04:43:00Z</published><updated>2011-11-09T04:43:00Z</updated><author><name>lovecindywang</name><uri>http://www.cnblogs.com/lovecindywang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lovecindywang/archive/2011/11/09/2242337.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lovecindywang/archive/2011/11/09/2242337.html"/><content type="html">&lt;p&gt;有一个很常见的功能，我们需要在一个子窗口中定时调用服务，然后更新控件的内容，只要窗口开着就一直会调用服务。&lt;/p&gt;  &lt;p&gt;那么现在就来完成这个功能，首先定义一个服务：&lt;/p&gt;      &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Service1 : IService1&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; DoWork(&lt;span class="kwrd"&gt;string&lt;/span&gt; name)&lt;br/&gt;        {&lt;br/&gt;            File.AppendAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, &lt;span class="str"&gt;&amp;quot;log.txt&amp;quot;&lt;/span&gt;), &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;&amp;quot;时间：{0} 线程：{1}&amp;quot;&lt;/span&gt; + Environment.NewLine, DateTime.Now, name));&lt;br/&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;OK&amp;quot;&lt;/span&gt;;&lt;br/&gt;        }&lt;br/&gt;    }&lt;p&gt;这个服务在返回数据之前会写一个本地文本日志，写入时间和传入的参数。&lt;/p&gt;&lt;p&gt;然后添加一个子窗口，并在页面上放置一个按钮打开这个窗口：&lt;/p&gt;ChildWindow1 c = &lt;span class="kwrd"&gt;new&lt;/span&gt; ChildWindow1();&lt;br/&gt;            c.Show();&lt;p&gt;子窗口的代码如下：&lt;/p&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ChildWindow1 : ChildWindow&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; Thread thread;&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; threadNum = 0;&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; ServiceReference1.Service1Client s = &lt;span class="kwrd"&gt;new&lt;/span&gt; ServiceReference1.Service1Client();&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; ChildWindow1()&lt;br/&gt;        {&lt;br/&gt;            InitializeComponent();&lt;br/&gt;&lt;br/&gt;            s.DoWorkCompleted += &lt;span class="kwrd"&gt;new&lt;/span&gt; EventHandler&amp;lt;ServiceReference1.DoWorkCompletedEventArgs&amp;gt;(s_DoWorkCompleted);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; s_DoWorkCompleted(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, ServiceReference1.DoWorkCompletedEventArgs e)&lt;br/&gt;        {&lt;br/&gt;            Dispatcher.BeginInvoke(() =&amp;gt; Message.Items.Insert(0, &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;&amp;quot;服务返回：{0} 控件：{1} 时间：{2} 线程：{3}&amp;quot;&lt;/span&gt;,&lt;br/&gt;               e.Result,&lt;br/&gt;               Message.GetHashCode(),&lt;br/&gt;               DateTime.Now,&lt;br/&gt;               e.UserState.ToString())));&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ChildWindow_Loaded(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;br/&gt;        {&lt;br/&gt;            Interlocked.Increment(&lt;span class="kwrd"&gt;ref&lt;/span&gt; threadNum);&lt;br/&gt;&lt;br/&gt;            thread = &lt;span class="kwrd"&gt;new&lt;/span&gt; Thread(state =&amp;gt;&lt;br/&gt;            {&lt;br/&gt;                var threadID = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)state;&lt;br/&gt;                &lt;span class="kwrd"&gt;while&lt;/span&gt; (&lt;span class="kwrd"&gt;true&lt;/span&gt;)&lt;br/&gt;                {&lt;br/&gt;                    s.DoWorkAsync(threadID.ToString(), threadID);&lt;br/&gt;                    Thread.Sleep(1000);&lt;br/&gt;                }&lt;br/&gt;            });&lt;br/&gt;            thread.Start(threadNum);&lt;br/&gt;        }&lt;p&gt;这个代码很简单：&lt;/p&gt;&lt;p&gt;1、我们有一个静态变量保存了总共的线程数&lt;/p&gt;&lt;p&gt;2、每次窗口打开+1&lt;/p&gt;&lt;p&gt;3、每次窗口打开的时候初始化一个线程，这个线程的作用就是不断调用服务，然后休眠1秒，调用的时候传入的参数就是当前线程编号（从1开始）&lt;/p&gt;&lt;p&gt;4、服务调用完成之后，我们会更新页面上的ListBox，添加一条数据，内容包括服务返回值、Message控件的标识、当前时间和后台线程的编号&lt;/p&gt;&lt;p&gt;好了，功能完成了，运行程序，我们的期望是在子窗口打开后：&lt;/p&gt;&lt;p&gt;1、子窗口的ListBox每一秒都会插入一行记录&lt;/p&gt;&lt;p&gt;2、服务端每一秒都会往文本文件写入一行记录&lt;/p&gt;&lt;p&gt;3、两者的线程编号保持一致，并且每次打开子窗口线程编号都会+1&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;运行程序，打开子窗口：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242426727.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242439626.png" width="501" height="238" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;看看服务端的日志：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242442068.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242456920.png" width="242" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;貌似完成了我们的需求，这个程序真的没问题吗？&lt;/p&gt;&lt;p&gt;第二次打开子窗口：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242451903.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242479579.png" width="438" height="176" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;也没问题，但是服务端的日志就不对了（看到没问题不代表真的没问题啊）：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242474562.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242488608.png" width="196" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;这说明两个后台线程同时在运行，不能想当然认为子窗口关闭了，老的线程会结束（可能会觉得反正不是静态字段嘛，窗口关闭了等它回收Thread去）。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242481639.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242483035.png" width="500" height="21" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242484114.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242481606.png" width="499" height="16" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Silverlight的程序一般很少刷新页面，随着子窗口开关越来越多，线程也越来越多，并且以前的线程会一直进行服务调用。&lt;/p&gt;&lt;p&gt;随着子窗口开关无数次，后台有无数个线程在调用服务端，想想也是很恐怖的事情！&lt;/p&gt;&lt;p&gt;前端显示一点问题都没有（为什么ListBox却没有多显示？大家可以思考一下），潜在增加了服务端的压力，我们希望的是再子窗口关闭之后，后台线程可以结束。&lt;/p&gt;&lt;p&gt;很多人可能会这么写：&lt;/p&gt;   &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ChildWindow_Closed(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (thread != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br/&gt;            {&lt;br/&gt;                &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br/&gt;                {&lt;br/&gt;                    thread.Abort();&lt;br/&gt;                }&lt;br/&gt;                &lt;span class="kwrd"&gt;catch&lt;/span&gt;&lt;br/&gt;                {&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;        }&lt;p&gt;子窗口关闭的时候结束线程嘛，反正它会抛ThreadAbortException，不用管了。&lt;/p&gt;&lt;p&gt;开关几次子窗口看看：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242497952.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242508343.png" width="218" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;还是一样，难道线程没结束？&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242509739.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242525703.png" width="439" height="214" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;想当然了！其实何必强制结束线程呢？让线程自己完成就可以了：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242526476.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242559833.png" width="395" height="402" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242552865.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lovecindywang/201111/201111091242563638.png" width="244" height="180" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;这样就正常了。当然，也可以使用BackgroundWorker来实现这个功能：&lt;/p&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Net;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Controls;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Documents;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Input;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Media;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Media.Animation;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Shapes;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Threading;&lt;br/&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.ComponentModel;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; SilverlightApplication2&lt;br/&gt;{&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ChildWindow1 : ChildWindow&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; threadNum = 0;&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; ServiceReference1.Service1Client s = &lt;span class="kwrd"&gt;new&lt;/span&gt; ServiceReference1.Service1Client();&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; BackgroundWorker bw = &lt;span class="kwrd"&gt;new&lt;/span&gt; BackgroundWorker();&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; ChildWindow1()&lt;br/&gt;        {&lt;br/&gt;            InitializeComponent();&lt;br/&gt;&lt;br/&gt;            s.DoWorkCompleted += &lt;span class="kwrd"&gt;new&lt;/span&gt; EventHandler&amp;lt;ServiceReference1.DoWorkCompletedEventArgs&amp;gt;(s_DoWorkCompleted);&lt;br/&gt;            bw.WorkerSupportsCancellation = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;br/&gt;            bw.WorkerReportsProgress = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;br/&gt;            bw.DoWork += &lt;span class="kwrd"&gt;new&lt;/span&gt; DoWorkEventHandler(bw_DoWork);&lt;br/&gt;            bw.ProgressChanged += &lt;span class="kwrd"&gt;new&lt;/span&gt; ProgressChangedEventHandler(bw_ProgressChanged);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; bw_ProgressChanged(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, ProgressChangedEventArgs e)&lt;br/&gt;        {&lt;br/&gt;            Message.Items.Insert(0, &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;&amp;quot;服务器返回：{0} 控件：{1} 时间：{2} 线程：{3}&amp;quot;&lt;/span&gt;,&lt;br/&gt;                e.UserState,&lt;br/&gt;                Message.GetHashCode(),&lt;br/&gt;                DateTime.Now,&lt;br/&gt;                e.UserState.ToString()));&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; s_DoWorkCompleted(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, ServiceReference1.DoWorkCompletedEventArgs e)&lt;br/&gt;        {&lt;br/&gt;            bw.ReportProgress(0, e.Result);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; bw_DoWork(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, DoWorkEventArgs e)&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="kwrd"&gt;while&lt;/span&gt; (!bw.CancellationPending)&lt;br/&gt;            {&lt;br/&gt;                var threadID = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)e.Argument;&lt;br/&gt;                s.DoWorkAsync(threadID.ToString(), threadID);&lt;br/&gt;                Thread.Sleep(1000);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ChildWindow_Loaded(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;br/&gt;        {&lt;br/&gt;            Interlocked.Increment(&lt;span class="kwrd"&gt;ref&lt;/span&gt; threadNum);&lt;br/&gt;            bw.RunWorkerAsync(threadNum);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ChildWindow_Closed(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br/&gt;        {&lt;br/&gt;            bw.CancelAsync();&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;p&gt;当然，本文标题虽然说Silverlight，对于Winform也是一样的，只不过Silverlight的Thread.Abort()不奏效。总之两点，一，有的时候不能太想当然和凭经验，只有实际验证了才知道结果；二，写.NET程序也不能啥都不释放不去管，对于线程、网络链接等资源、大量内存分配还是需要多关注。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lovecindywang/aggbug/2242337.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lovecindywang/archive/2011/11/09/2242337.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
