《C#典型模块与项目实战大全.doc》由会员分享,可在线阅读,更多相关《C#典型模块与项目实战大全.doc(19页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第1章 .NET 4.0体系结构微软公司每隔几年就会对其开发工具与平台进行升级,使得开发人员能更高效、更快速地开发高可用性的应用程序。.NET Framework 4.0是最新的一个版本。该版本与.NET Framework的早期版本是可以同时存在的。本章将从体系结构方面讲解.NET 4.0的新功能及其与.NET早期版本的不同之处,同时对于微软新的Visual Studio 2010的使用方法进行详细介绍。1.1 C#与.NET的关系C#是微软公司为了支持.NET框架而研发的一门语言,它具有Java的简洁、C+语言的灵活,并且有Pascal语言的严谨,是一门非常优秀的开发语言。.NET框架是一
2、个应用程序开发平台,C#是为支持这个框架而开发的,它们具有非常密切的联系。作为一个.NET开发者,学会使用C#语言是非常有必要的。C#与.NET之间的关系是非常密切的。C#只是一门语言,而且它是伴随着.NET出现的语言,用C#语言编程时,需要使用.NET框架类库来进行开发。但是与.NET框架相关的语言不止C#一种,开发人员可以使用Visual Basic.NET或者其他一些支持.NET的语言进行程序设计。1.1.1 .NET Framework 4.0简介微软公司自从发布.NET Framework 1.1以来,已历经了4个版本。微软不断地改善原有版本的缺陷和不足,不断地推出新的功能,到现在的
3、4.0版本,已经成为了一个功能强大的应用程序开发平台,其发展路线如图1.1所示。.NET Framework提供了一整套应用程序开发平台,它实际上由一大堆技术组合而成,这些技术彼此协作,能为开发人员提供无限的可能。归根结底,.NET Framework由如下几大部分组成。q .NET语言:包括Visual Basic.NET、C#、JScript.NET、J#和C+等。q 通用语言运行时(CLR):提供所有.NET程序的执行引擎,并为这些应用程序提供自动化服务,比如安全性检查、内存的管理和应用程序的优化等。q .NET框架类库:包含大量内置的功能函数,使应用程序的开发人员可以更轻松地使用它提供
4、的功能来实现应用程序的开发。这些类库被组织为几个技术集,比如ASP.NET、Windows Forms、WPF、WCF、WF、Silverlight、网络编程等。q Visual Studio:功能强大,使用简便的集成化开发环境,具有一整套高效的功能集合和调试特性。图1.1 .NET 版本发展路线图在MSDN中,把整个.NET Framework分为两大类:一类是通用语言运行时(CLR),另一类就是.NET Framework类库。通用语言运行时是整个.NET应用程序的核心,无论使用什么样的语言,编写什么样的.NET程序,都需要这个核心引擎所提供的核心功能。图1.2是.NET Framewor
5、k的基本结构图,该图将.NET划分为两大部分,每一部分内部又细分了各种不同的功能模块。在类库部分,可以看到提供了很多开发人员常见的应用程序类型,基本上.NET程序员都在与.NET Framework中庞大的类库打交道。通用类型系统为.NET应用程序提供了一个托管的平台,它提供了较底层的功能,通常开发人员较少需要处理CLR的部分。图1.2 .NET Framework基本结构微软公司自从推出第一个.NET Framework以来,不断地升级和精炼这套框架的可用性。到目前为止,已经发展到.NET 4.0版。这一版本的.NET Framework除了修正和提升了原有框架的不足之处以外,还增加了很多新
6、的开发类库,比如WPF、WCF和WF这3套开发基础库。要深入理解.NET Framework这个大框架的架构,首先需要深入理解其核心部分,即CLR。1.2节将会详细介绍。1.1.2 LINQ语言集成查询在LINQ出现之前,当访问数据源时,开发人员不得不掌握特定数据来源的数据访问方法。比如要读取和写入XML数据,必须掌握操作XML的方法;要访问数据库,必须掌握ADO.NET技术等。语言集成查询(Language Integrated Query,LINQ),如其名称所暗示,在开发语言如C#或者是VB.NET中集成了数据查询功能,这个功能的出现让开发人员可以不用了解异构数据源的细节,便能使用一种统
7、一的方式来访问数据源,使开发人员可以专注于业务逻辑的设计。图1.3是LINQ的结构图。从图中可以看到,LINQ允许的数据源中,LINQ的可查询能力可分作3大类:LINQ To Objects、LINQ To ADO.NET及LINQ To XML。下面对这3大类LINQ的组成部分进行简要介绍。q LINQ To Objects:可以从任何实现了IEnumerable接口的对象中查询数据。q LINQ To ADO.NET:增强了LINQ To Objects,使之可以访问关系型数据库。从图1.2中可以看到,其主要由3个部分组成:LINQ To SQL,用于查询关系型数据库,例如SQL Serv
8、er等;LINQ To Datasets,支持查询DataSet或DataTable;LINQ To Entities,是Microsoft ORM解决方案,允许开发人员使用实体(Entities)声明性的指定商业对象(business objects)的结构,并且使用LINQ进行查询。q LINQ To XML(以前称为XLinq),不仅包括LINQ To Objects的功能,还可以查询和创建XML文档。图1.3 语言集成查询LINQ结构例如,对于关系型数据库来说,通常使用SQL语句来查询数据库。要查询Northwind数据库中employees表的Name字段,使用SQL语句语法如下所示
9、。Select name from employees使用LINQ语法的话,语法与之类似,代码如下所示。var query=form e in employeesselect e.name可以看到代码与SQL语句非常相似,但是使用LINQ,让开发人员可以用相同的语法查询异构数据源。比如一个employees的对象的集合,或是来自Oracle数据库的数据,都可以使用相同的语法进行查询。1.1.3 WPF表现层技术简介WPF是一种基于矢量绘图引擎的用户界面技术,也可以称其为下一代的显示系统。WPF可以让具有创造力的设计人员设计具有震撼视觉体验的Windows客户端应用程序的用户界面,也可以使用其子
10、集Silverlight创建具有创造力的Web Base应用。WPF有如下几项重大的功能特色。q 基于矢量的绘图技术:WPF基于DirectX,可以最大化地利用显示卡的性能。基于矢量绘图技术,可以无限地放大和缩小图形。WPF利用Direct3D进行图形着色,充分利用显示卡的绘图单元。q 采用声明式的程序设计:使用派生自XML的XAML标记语言来声明式的设计UI,设计人员也可以选择微软的Expression Blend设计软件进行UI部分的可见即所得的设计。q Web样式的布局模型:增强了流式布局模型的体验,除了使用坐标进行布局外,还可以使用流动式布局排列用户控件。q 强大的绘图功能的支持:除了
11、支持基本图形、文本块外,还提供了很多绘图特性,比如透明度及内置的3D支持。q 与多媒体、动画技术的完美整合:设计人员可以使用XAML标记或借助于Expression Blend软件来设计用户界面动画。q 样式和模板:用于重用已有的样式设定,使用模板可以改变元素的显示方式,使用样式可以为控件形成换肤效果。1.1.4 WCF通信层技术简介WCF是一种统一的技术,是微软基于SOA(Service Oriented Architecture,面向服务的架构)所推出的.NET平台下的开发框架。WCF是微软分布式应用程序开发的最新开发框架,它整合了.NET平台下的分布式开发技术,比如.NET Remoti
12、ng、Web Service和MSMQ等,使开发者可以创建一个跨平台的、安全可信赖,以及事务性的解决方案。WCF具有如下3大基础概念。q 消息和终结点:WCF建立在基于消息通信的基础之上,可以用消息表示的任何内容,如HTTP请求和MSMQ消息都可以使用一种统一的编程模型来表示。这样,可以在不同的传输方式中提供统一的API。消息在终结点之间传送,终结点是发送或接收消息的场所,终结点定义消息交换所需要的所有信息。q 通信协议:元素的传输协议,在WCF中这是必需的。可以使用常用的传输协议如HTTP和TCP,可以通过局域网或互联网来发送消息,也可以使用其他支持与MSMQ应用程序和对等网上的节点进行通信
13、的传输协议,而且使用WCF的可扩展特性可以添加更多的传输机制。通信堆栈中另一个必要的元素是消息格式的编码,在WCF中,可以使用文本编码、消息传输优化机制编码及用于实现高效传输的二进制编码。q 消息模式:WCF支持多种消息模式,不同的传输协议支持不同的消息模式,包括请求-回复模式、单向模式和双工通信模式。关于更多WCF编程的细节知识,读者可以参考MSDN上的WCF内容或专门介绍WCF的书籍。1.1.5 WF工作流基础简介WF是微软在.NET 3.0之后推出的一套工作流开发框架。目的在于为现有的.NET应用程序嵌入工作流应用。WF不是一个独立的工作流应用程序,它提供了一些类库用于辅助工作流应用程序
14、的开发,并提供了实现工作流应用程序时所需要实现的一些机制,比如持久化、补偿、跟踪机制等。首先必须要明白,WF不是某一领域或通用领域的工作流应用程序,它是一种编程模型、一个工作流的引擎,主要目的是在Windows上快速启用工作流的应用程序。使用WF可以处理的解决方案如下:q 可以为业务流程应用程序启用工作流;q 用户界面页面流;q 文档工作流系统;q 人工工作流;q 业务规则驱动的工作流;q 系统管理工作流。WF有以下几个基本特点。q WF具有强大和灵活的工作流开发能力,使用Visual Studio提供的可视化设计工具和WF的运行时引擎,让开发人员能够以一种统一的方式开发应用程序。q WF支持
15、顺序工作流、状态机工作流和数据驱动工作流风格,并且支持工作流的持久化。这对于一些需要一天甚至一年之后再继续的工作流来说非常有用。q WF支持使用特定领域模型解决问题,开发人员可以开发自己的活动组件,来引入对于特定领域问题的解决方法。q WF提供了完整的工作流开发系统,除了工作流运行时本身,微软也提供了一套标准的活动、工作流持久化、工作流监控和追踪、规则引擎、与VS紧密整合的工作流设计器,以及项目开发模板等。q 可以修改WF的默认行来扩展WF,比如可以提供自定义的持久化服务来取代WF提供的SQL持久化服务。q 对于企业来说,最重要的是WF包含在Visual Studio中,无须花费额外成本。1.
16、1.6 Windows CardSpace技术简介随着Internet的普及以及用户对于网络的依赖性的增强,越来越多的安全性问题也暴露出来,比如用户的个人信息和账户的安全性问题。随着网龄的增加,用户必须记住越来越多的账户和密码,以及许多网站重复使用相同的账户名和密码。微软在.NET 3.0中推出了CardSpace标识元系统的实现,使用户能够从标识公文包中选择标识,并在接受这些标识的环境中使用这些标识。在安装了.NET Framework 4.0之后,控制面板中会增加一个名为Windows CardSpace的选项,选择该项之后,将会弹出一个编辑或查看卡片的窗口,用户可以在该窗口中输入卡片,或
17、导入一个托管卡片,如图1.4所示。然后可以对应用程序进行编写代码,以便能够从标识管理器中选出一种标识进行用户的统一身份验证。图1.4 控制面板中的创建卡片对话框1.2 公共语言运行时公共语言运行时(Common Language Runtime,CLR)是一个和Java虚拟机一样的运行时环境,主要负责资源的管理,比如内存分配和垃圾收集,以保证应用和底层操作系统之间的分离。简而言之,.NET框架能保证用户可以使用多种语言进行.NET应用程序的开发和交互,因为CLR实现了通用语言基础架构(Common Language Infrastructure,CLI)。1.2.1 通用语言基础架构CLI通用
18、语言基础架构定义了构成.NET Framework基础结构的可执行代码,以及代码运行时的环境规范。它定义了一个与语言无关的跨体系结构的运行环境,这使得开发者可以用规范内定义的各种高级语言来开发软件,并且无须修正即可将软件运行在不同的计算机体系结构上。%注意:CLI与CLR不要混用,CLI是一种规范,而CLR是这种规范的一种实现。CLI是一个开发型的技术规范,由微软、惠普和英特尔于2000年向ECMA倡议的,在CLI中包含以下几个重要的部分。q 通用类型系统(CTS):规范.NET中数据的类型。q 元数据系统(Metadata):是.NET中描述数据的数据。q 通用语言规范(CLS):描述多语言
19、之间进行交互的语言规范,.NET系统包括的语言有C#、C+、VB、J#,它们都遵守通用语言规范。q 虚拟执行系统(VES):是一个可运行受管理代码(Managed Code)的运行环境,它提供了运行受管理代码所需要的内置数据类型(data type),以及假定的机器型态与状态设置、流程控制与例外处理等参数。整个CLI的架构如图1.5所示。图1.5 CLI架构.NET的系统结构是非常庞大和复杂的,要想全面了解,需要学习大量的知识。读者可以参考MSDN中的介绍。1.2.2 CLR的作用有了公共语言运行时,开发人员就可以很容易地设计出对象能够跨语言交互的组件和应用程序。也就是说,用不同语言编写的对象
20、可以互相通信,并且它们的行为可以紧密 集成。例如,可以定义一个类,然后使用不同的语言从原始类派生出另一个类或调用原始类的方法。还可以将一个类的实例传递到用不同的语言编写的另一个类的方法。这种跨语言集成之所以成为可能,是因为基于公共语言运行库的语言编译器和工具使用由公共语言运行库定义的通用类型系统,而且它们遵循公共语言运行库关于定义新类型,以及创建、使用、保持和绑定到类型的规则。相对于过去的一些开发平台(比如Delphi),.NET CLR有如下优点:q 跨语言集成,特别是跨语言继承,使得用VB.NET写的类能轻松的被C#类继承。q 垃圾回收,它管理对象生存期,使引用计数变得不再必要,程序员无须
21、关心类的释放问题,一切都由CLR的垃圾回收器在后台回收。q 自我描述的对象,它使得使用接口定义语言(IDL)不再是必要的,使用.NET反射可以很轻松地获取到运行时类型信息。q 编译一次即可在任何支持公共语言运行时的CPU和操作系统上运行的能力。1.3节将深入到语言层次,对C#语言的新特性进行讲解。1.3 C# 4.0的新增特性回顾C#语言的发展,从1.0到现在的4.0,每一个版本都会增加一些激动人心的特性。比如2.0加入了对泛型的支持,3.0新增了一些语法特性以支持LINQ等开发框架,在C# 4.0中增加了动态语言等特性。要全面理解C#语言,需要全面掌握这些已有的功能和新增特性,这样才能最大限
22、度地发挥C#语言的功能。1.3.1 C# 4.0面向对象编程简介C#是一门纯面向对象的语言。在C#语言中连基本的数据类型都是派生于System.object的类型,比如int、double等。与使用Java语言一样,应该具有万事万物皆对象的理念来使用C#进行程序设计,这需要读者具有良好的面向对象编程的思想。编程是一个非常抽象的工作,需要将现实世界中的实体转化为电脑软件。面向对象的思想要求用户具有对现实世界中的事物进行抽象的能力。比如在开发一个生产管理软件时,所有与生产管理相关对象,包含工人、产品、生产单、异常等,都是一个个的对象。那么在编写C#代码时,应该仔细考虑这些现实世界中的对象,然后进行
23、分析和对象化。对象具有属性和方法,以及与这些属性和方法相关联的一系列的事件。比如生产管理软件中,如果工人是一个对象的话,那么年龄、性别就是工人这个对象的属性;可以将工人工作这个行为当作是工人这个对象的方法;到了下班的时间工人要下班,可以将在这个时间触发的行为称之为事件。下面的示例将使用微软公司最新的Visual Studio 2010创建一个C#控制台应用程序,演示如何使用C#创建一个类,并添加属性和方法。步骤如下:(1)打开Visual Studio 2010,选择“文件”“新建”“项目”命令,从弹出的窗口中选择Visual C#|Windows |“控制台应用程序”命令,如图1.6所示。在
24、名称窗口中输入应用程序的名称为ClassDemo,指定文件所要保存的路径,单击“确定”按钮,Visual Studio将自动创建一个控制台应用程序项目,并且进入到代码录入窗口。图1.6 新建控制台应用程序(2)在代码输入窗口中编写一个名为Worker的类,表示一个生产管理系统中的工人,他具有姓名、性别、年龄属性和一个名为Working()的方法,如代码1.1所示。代码1.1 Worker类定义代码/ / 生产管理系统中的工人类/ public class Worker public event EventHandler OffWork; /下班事件 public string Name get
25、; set; /姓名 public int Age get; set; /年龄 public bool IsBoy get; set; /是否男生 public void Working() /正在工作的方法 Console.WriteLine(姓名:0,性别1,年龄2 正在工作中.,Name,IsBoy,Age); if (DateTime.Now.Hour = 14) /如果是下午2点,则提示已下班 if (OffWork != null) /要判断该事件是否被赋值 OffWork(this, new EventArgs(); /调用下班事件处理代码 在上面的代码中,使用了C# 3.0以来
26、的属性简化语法来定义了3个属性,使用泛型的EventHandler定义了一个事件句柄。Working事件中首先在控制台窗口中打印一行Worker类当前的属性信息,然后在当前时间为14时触发OffWork事件,如果当前时间是下午2点时,将触发用户定义的一段事件处理代码。(3)在控制台的主应用程序中编写代码实例化这个Worker类,然后设置这个Work类的属性,并调用Worker类的方法,如代码1.2所示。代码1.2 实例化Worker类代码class Program static void Main(string args) Worker worker = new Worker(); /实例化一
27、个Worker类 worker.Name = 一个工人; /设置姓名属性 worker.Age = 18; /设置年龄属性 worker.IsBoy = true; /设置性别属性 worker.OffWork += /关联一个下班的事件处理代码 new EventHandler(worker_OffWork); worker.Working(); /调用类的方法 Console.ReadLine(); /暂停屏幕关闭 /员工下班的事件处理代码 static void worker_OffWork(object sender, EventArgs e) Console.WriteLine(该员
28、工到点已下班了!); 代码1.2使用new语法创建了一个生产工人,然后指定工人的姓名、性别和年龄,为工人下班事件关联了一个名为worker_OffWork()的方法,最后调用Working类方法开启员工工作。程序运行效果如图1.7所示。在将当前系统时间调到下午2点多以后,控制面板窗口中会显示出该员工已经下班的信息。图1.7 对象示例运行效果本节只能对C#面向对象的知识进行简单介绍,完整介绍面向对象的理论和C#进行面向对象的编程需要很多篇幅,读者可以参考一些专门介绍面向对象的书籍。1.3.2 强数据类型强数据类型是指必须为变量指定一个数据类型,C#本身是一门类型安全的编程语言,类型访问必须根据所
29、指定的数据类型来访问,比如将一个字符串类型当作一个整数类型来访问是不被允许的。C#本身支持静态类型检查,因此在编译时强制类型安全,.NET的通用语言运行时将强制执行动态类型安全检查,以便在程序运行前就能消除类型转换的错误。Visual Studio的智能提示功能,可以通过静态类型检查发现错误的类型操作。如图1.8所示,当为一个整型赋一个字符串时会提示类型不能正确转换。由于C#的类型规则非常的严格,即使将一个浮点数传递给一个接受整型的函数,如果不进行强制类型的转换,也将会出现错误。使用强类型的这种特性,可以使C#代码运行在一个安全的、受控的环境中不至于被其他方面破坏。图1.8 Visual St
30、udio 2010类型检查提示1.3.3 动态类型绑定动态绑定是C# 4.0中非常重大的创新,它的出现类似于在C# 2.0中的泛型一样。动态绑定的灵感来源于一些如Python、Ruby、JavaScript和Smalltalk等动态语言。动态绑定的定义是:将解析类型和成员的过程由编译时延迟到运行时。C#是一种强数据类型的语言,因此在编译时已经决定了其数据类型,即便是使用Var关键字的隐式类型声明,在编译时仍然会变成确切的类型。而动态绑定声明是指在编译时并不知道它引用对象的确切类型,在运行时才知道。下面新建一个控制台应用程序名为DynamicBindingDemo,编写动态绑定的代码见代码1.3
31、。代码1.3 动态绑定示例代码class Program static void Main(string args) dynamic obj = new DynTypeObject();/定义动态对象 obj.Working(); /调用动态方法 obj.WorkingOthers(); Console.ReadLine(); /暂停控制台屏幕 public class DynTypeObject : DynamicObject/创建一个动态绑定对象 /重载调用成员方法 public override bool TryInvokeMember(InvokeMemberBinder binder
32、, object args, out object result) Console.WriteLine(binder.Name + 方法正在调用);/在控制台显示信息 result = null; return true; /返回布尔值 在上面的代码中,DynTypeObject对象是一个动态绑定的对象。可以看到,Working()和WorkingOthers()实际上并没有进行定义,但是在运行时可以看到这两个方法被成功调用,如图1.9所示。图1.9 动态方法调用以传统的眼光来看,DynTypeObject是一个派生自DynamicObject的普通的类。它并没有定义Working和Worki
33、ngOthers方法。如果不是派生自DynamicObject,运行这段代码将会产生异常。这是因为.NET是强数据类型的,而DynamicObject使得调用在运行时动态的产生,因此输出了如图1.9所示的结果。1.3.4 泛型类型的协变(covariant)和逆变(contravariant)在.NET 4.0之前的版本中,泛型类型是不支持协变和逆变的,但是委托类型的参数是支持协变和逆变的。什么是协变和逆变呢?在编程语言中,“协变”是指能够使用与原始指定的派生类型相比派生程度更大的类型;“逆变”则是指能够使用派生程度更小的类型。下面的代码很好地演示了委托类型的协变。假定有一个类Animals,
34、从其派生出一个子类Dogs,那么当定义一个委托,该委托返回Animals。用户也可以将一个返回Dogs的委托赋值给该委托,称之为协变,见代码1.4。代码1.4 委托的协变class Program public delegate Animals HandlerMethod();/返回Animals的委托 public static Animals FirstHandler() /返回Animals的方法实现 Console.WriteLine(返回Animals的委托); return null; public static Dogs Secondhandler() /返回Dogs的方法实现
35、Console.WriteLine(返回Dogs的委托); return null; static void Main(string args) HandlerMethod handler1 = FirstHandler; /标准委托 HandlerMethod handler2 = Secondhandler;/委托协变 / 定义一个Animals的类 public class Animals public string Location get; set; / 定义一个派生自Animals的Dogs类 public class Dogs : Animals public string Cr
36、y get; set; 在上面的代码中,首先定义了Animals类和Dogs类,然后定义了一个名为HandlerMethod的委托,该委托返回Animals类型的值。在Main()方法中,分别赋给一个返回Animals类型的值和一个返回Dogs类型值的方法。可以看到,由于委托的协变特性,使得本来返回一个Animals的委托可以接受一个返回Dogs的委托。.NET 4.0引入了in/out参数,使泛型类型的协变和逆变得以实现。比如定义一个泛型接口或者是泛型委托,可以使用out关键字,将泛型类型参数声明为协变。协变类型必须满足条件:类型仅用作接口方法的返回类型,不用作方法参数的类型。可以使用in关
37、键字,将泛型类型参数声明为逆变。逆变类型只能用作方法参数的类型,不能用作接口方法的返回类型。逆变类型还可用于泛型约束。下面的示例演示了如何使用in/out参数来设置泛型类型的协变和逆变。协变的使用见代码1.5。代码1.5 泛型的协变interface ITest /定义一个支持协变的接口 T X get; /属性 T M(); /返回T类型的方法/定义一个实现接口的泛型类class TestClass : ITest where T : Base, new()/约束T要派生自Base,具有构造函数 public T X get; set; /实现泛型方法 public T M() return
38、 new T(); /定义两个类class Base class Derived : Base class Program static void Main(string args) ITest _derived = new TestClass X = new Derived() ;/使用对象初始化语法赋初值 ITest _base = _derived; /泛型协变 Base x = _base.X; Base m = _base.M(); 在上面的代码中,定义了一个泛型接口ITest,注意使用了out参数以支持协变。然后TestClass泛型类实现了接口,并且定义了泛型约束指定T类型必须是
39、派生自Base类的子类。可以看到在Main主窗体中,定义了一个ITest的接口,然后利用泛型的协变特性来进行泛型类型之间的变换。与协变相反的是,逆变是将基类转换为派生类,泛型逆变有如下两条规则:q 泛型参数受in关键字约束,只能用于属性设置或委托(方法)参数。q 隐式转换目标的泛型参数类型必须是当前类型的“继承类”。例如,代码1.6定义了一个接口,演示了哪些是允许协变,哪些是允许逆变的。代码1.6 接口的逆变interface ITest T X get; /获取属性不允许逆变 set; /设置属性允许逆变! T M(T o); /只允许方法参数,不能作用于方法返回值与协变相反,逆变符合多态性
40、的规律,逆变有些令人费解,不过逆变主要是为泛型委托准备的。逆变的使用如代码1.7所示。代码1.7 委托的逆变class Program static void Main(string args) Action _base = (o) = Console.WriteLine(o);/定义一个Base基类 Action _derived = _base;/使用协变将基类转换为派生类 _derived(new Derived();/逆变的效果 以上代码中创建了一个委托,是基于Base类,但是在后面的赋值语句中,将基类赋给派生类,形成了逆变。1.3.5 命名参数和可选参数C# 4.0新增的功能在MSD
41、N中有详细介绍,本书不再一一介绍。本节将介绍命名参数和可选参数。q 命名参数允许一个函数调用者通过名称,而不是参数所在的位置来标识一个参数。q 可选参数允许函数指定一个默认值,这样调用方在调用时可以省略默认值。命名参数语法示例如代码1.8所示。代码1.8 委托的逆变class Program static void Main(string args) NamedParameters(P1: 命名1, P2: 命名2, P3: 命名3); /使用命名参数语法 static void NamedParameters(string P1,string P2,string P3)/自定义函数 Cons
42、ole.WriteLine(参数1:0,参数11,参数22, P1, P2, P3); 可以看到,命名参数命名的方式指定参数,不用关注参数的位置,而且Visual Studio 2010还提供了参数提示功能。可选参数的示例如代码1.9所示。代码1.9 委托的逆变/定义一个带有可选参数的参数,指定默认值static void ShowText(string text = 这是默认的文本) Console.WriteLine(text); static void Main(string args) ShowText(); /调用时不传递参数,将使用默认参数 Console.Read();可以看到,
43、在定义函数时指定了参数的默认值,在调用时可以不指定参数,将会使用默认的参数进行代替。本节介绍了一些C# 4.0新增的特性。当然C#新增的功能还有很多,有兴趣的读者可以参考MSDN中的内容。下面一节将讨论如何使用全新的Visual Studio 2010集成化开发环境。1.4 使用Visual Studio 2010集成化开发环境Visual Studio 2010是微软公司集成化开发环境的最新版本,微软一共发布了如下4个版本的Visual Studio 2010。q 2010 Professional 专业版:适用于个人执行基本开发任务。q 2010 Premium 企业版:适用于个人和团队开发可扩展的高质量的应用程序。q 2010 Ultimate 旗舰版:ALM 工具适用于团队,可确保从设计到部署均获得高质量成果。q Test Professional 2