




已阅读5页,还剩88页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1,LINQ从入门到精通,Web开发框架技术初级 天津理工大学华信软件学院 张一鸣 2011年6月24日,第一章 LINQ简介,2011年6月24日,Web开发框架技术初级,3,本章主要内容,本章主要介绍LINQ的基本概念和组成,它的工作原理,以及几种不同的实现形式。,语言集成,LINQ如何工作,LINQ是什么,为什么需要LINQ,语言集成,4,LINQ?,LINQ是Language Integrated Query的缩写,意即语言集成查询) 。它有许多种解释,例如: LINQ是各种类型数据的统一编程模型。它允许使用独立于数据源的一致模型查询和操作数据。 LINQ是另外一种可以把SQL查询嵌入代码的工具。 LINQ是另外一种数据抽象层。 所有这些说明在某种程度上是正确的,但是都只说明了LINQ的一个方面。实际上,LINQ是一种全新的查询工具。,5,1.1 LINQ是什么,LINQ是一个把查询当作头等概念引入所有微软.NET语言的编程模型。但是,现有的编程语言完全支持LINQ还需要添加一些扩展内容。经过扩展,LINQ提供了一种简化和统一各种类型数据访问实现的方法。它可以很容易地利用几种现有的体系结构来访问数据,例如: RAD/原型 客户端/服务器 三层/多层体系结构 智能客户端,6,LINQ和.NET语言的关系,启用LINQ的数据源 ADO.NET LINQ技术,C#,其他,VB,.NET语言集成查询LINQ,LINQ to DataSet,LINQ to SQL,LINQ to Entities,LINQ to Objects,LINQ to XML,启用LINQ的数据源 ADO.NET LINQ技术,对象,关系,XML,7,.NET各个版本的关系,NET 2.0 CLR WinForms WebServices ASP.NET,NET 3.0,WCF WF WPF,CardSpace,LINQ AJAX REST,NET 3.5,.NET 2.0是整个.NET的核心 .NET3.0是在.NET 2.0的基础上增加了WPF、WCF、WF、CardSpace等跟Vista有关的组件 .NET 3.5除了包含.NET 3.0的全部功能外,增加了对LINQ、Ajax等技术支持的全新框架库和编译器,8,LINQ的发展经历,作为微软Visual Studio 2005的 扩展内容以技术预览的形式首先发布,2008,2007.11,2005.9,包含了LINQ to Objects和 LINQ to ADO.ENT三大模块 块后正式发布,增加LINQ to Entities组件及扩展后发布,9,1.2 为什么需要LINQ,原来的SQL只能访问包含在结构化的关系型数据库中的数据。但是现实世界中,数据可以存储在各种各样的数据源中,比如数组、对象图、XML文档、数据库、文本文件、注册表项、网页、电子邮件信息、简单对象访问协议(SOA P)消息内容、微软的Excel电子表等,特别是大量非结构化数据,都是用SQL无法访问的。,10,例子1.1 一个简单的LINQ查询程序,using System; using System.Linq; string greetings = “hello world”, “hello LINQ”, “hello Apress” ; var items = from s in greetings where s.EndsWith (“LINQ”); select s; foreach ( var item in items ) Console.WriteLine ( item ); 在vs2008中创建这个工程,编辑程序、编译、链接,执行,在具有三个元素的字符串数组执行LINQ 查询。显示结果为:,hello LINQ,11,访问数据源的数据模型,每种数据源都有自己特有的数据访问模型。比如,查询数据库时,一般都使用SQL,操纵XML数据时,则使用文档对象模型MOD或XPath/XQuery。使用不同的编程模型可以访问不同的数据源。但是这造成程序员在编写程序时,当访问不同的数据源时,要采用不同的方法编写,增加了开发、调试和维护的工作量与复杂性。 为了解决这个问题,软件界做了大量工作,尝试把各种数据访问技术统一成一个综合的模型,如利用Windows管理规范以ODBC访问Excel等。,12,LINQ技术的独特方法,LINQ在总结了以前的经验后,没有走统一各种不同的数据模型的结构从而建立一个“通用”模型的方法,而是利用不同数据模型中操作具有的通用功能来实现这个目的。 换句话说,使用LINQ时,仍然维持现有的各种数据结构,比如类或表,并且不管这些数据类型表示何种物理意义,但是都用统一的查询语法对异种数据进行查询。例如对于内存中的数组和数据库中的关系表中的数据,使用LINQ就可以对他们使用相同的查询语法。,13,例子1.2 一个简单LINQ查询,设计一个LINQ查询,在Customers数据表中搜索所属国籍是意大利的那些公司的名称,代码如下所示: var query = from c in Customers where c.Country = “Italy” select c.CompanyName; 该查询返回的结果是一个字符串列表,可以用C#语句按照枚举的方式显示这些返回值,即: foreach ( string name in query ) Console.WriteLine ( name ); ,14,简单LINQ查询的说明,var、query和foreach都是标准的C#3.0的语句,分别表示执行的LINQ查询和对于对象的循环控制。在其中添加一个名为Search.ascx的文件 c、Customers是已定义的实体类。 from、where、select都是LINQ的关键字,分别表示指定数据源、查找条件和确定要查找的数据内容。,15,关于Customers的讨论,上例中的Customers可以是: 对象集,例如:Customer Customers; 数据集中的DataTable,例如: DataSet ds = GetDataSet( ); DataTable Customers = ds.Tables“Customers” ; 描述关系型数据库中物理表的实体类,例如: DataContext db = new DataContext ( ConnectionString ); Table Customers = db.GetTable(); 描述概念模型并被映射到关系型数据库中的实体类,例如: NorthwindModel dataModel = new NorthwindModel( ); ObjectQuery Customers = dataModel. Customers;,16,LINQ构件块、LINQ提供器和相应数据源,LINQ构件块,编程语言: C# VB.NET Others,标准查询操作符,查询表达式,表达式树,LINQ提供器,LINQ to DataSet,LINQ to SQL,LINQ to Entities,LINQ to Objects,LINQ to XML,数据源,对象,RDBMS,XML,DataSet,ADO.NET Entity框架,?,Others,17,我们知道,在一般编程语言中执行SQL查询时,是把SQL语句嵌入到程序中。这些SQL语句没有集成到编程语言本身的语法和类型系统当中,因此编程和调试时都比较麻烦。 与SQL不同,LINQ则是集成到开发语言当中的查询语言,而且它不仅局限于查询数据库,还可以查询对象、实体、XML文档等非结构化的数据。 那么,LINQ 是如何工作的呢?,1.3 LINQ如何工作,18,LONQ查询的处理过程,使用LINQ编写查询代码时,如下例: C#编译器会生成下列代码:,Customer Customers = GetCustomers( ); var query = from c in Customers where c.Country = = “Italy” orderby c.Name select new c.Name, c.City ;,Customer Customers = GetCustomers( ); IEnumerableCustomer query = Customers .where ( c = c.Country = = “Italy” ); .OrderBy ( c = c.Name ) .Select ( c = new c.Name, c.City ;,19,LINQ对宿主语言的扩展,从上面的例子可见,首先在Customers上调用Where,然后在Where返回的对象上调用OrderBy进行排序,最后在OrderBy返回的对象上调用Select。这是由使用的宿主语言(C#)中的扩展方法(LINQ)在管理这种查询行为。 该例子中的查询调用的Where、OrderBy、Select方法的实现形式,取决于Customers的类型(即前述的对象集、数据表、关系型数据库中物理表的实体类、概念模型并被映射到关系型数据库中的实体类),同时也取决于相关的using语句指定的命名空间。扩展方法是LINQ使用的基础语法特征,LINQ就是采用这种相同的语法来操作不同的数据源。,20,LINQ对于数据的适时操作,LINQ查询只有在需要使用其返回结果时才会执行,否则它不会被执行。例如,下面的例子中,仅当执行foreach循环语句时才执行LINQ访问: var query = from c in Customers (非冯结构) foreach ( string name in query ) 迭代LINQ查询返回结果并在内存中生成持久性数据副本的方法也是这样: var query = from c in Customers (非冯结构) List Customers = query.ToList( );,21,LINQ对于数据库的延迟访问,当LINQ查询操作关系型数据库(比如SQL Server)中的数据时,它将生成等价的SQL语句,而不会操作内存中的数据表的副本。 并且,LINQ对数据库的查询将被延迟,直至首次访问该查询结果为止。 若前两个例子中,Customers是Table类型(物理表)或ObjectQuery类型(概念实体),在执行foreach循环语句之前,或者在调用ToList方法之前,都不会把等价的SQL查询发送到数据库。,22,例子1.3 用LINQ查询XML,using System; using System.Linq; using System.Xml.Linq; XElement books = XElement.Parse ( ” Pro LINQ: Language Integrated Query in C# 2008 Joe Rattz Pro WF: Windows Workflow in .NET 3.0 Bruce Bukovics Pro C# 2005 and the .NET 2.0 Platform, Third Edition Andrew Troelsen ”);,23,例子1.3 用LINQ查询XML (续),var items = from book in books.Elements (“book”) where (string) book. Element (“author”)= “Joe Rattz” ; select book.Element (“title”); foreach ( var title in titles ) Console.WriteLine ( title.Value ); 在vs2008中创建这个工程,编辑程序、编译、链接,执行。显示结果为: 本例没有创建一个XmlDocument,而是把XML数据解析为XElment类型的对象,很方便的对XML API进行了扩充。,Pro LINQ: Language Integrated Query in C# 2008,24,例子1.4 用LINQ查询SQL数据库,using System; using System.Linq; using System.Data.Linq; using nwind; Northwind db = new Northwind ( “Data Source = .SQLEXPRESS; Initial Catalog= Northwind” ); var custs = from c in db.Customers where c.City = “Rio de Janeiro” select c; foreach ( var cust in custs ) Console.WriteLine (“0”, cust.CompanyName );,25,例子1.4的分析及运行结果,本例代码要在工程中添加对System.Data.Linq.dll程序集的引用。 添加using System.Data.Linq指令是为使用SQL数据库。 添加using nwind指令是为使用微软的Northwind示例数据库,必须使用SQLMetel命令行工具为目标数据库生成实体类,这个生成的实体类被创建在nwind命名空间中。 本例的运行结果为:,Hanari Carnes Que Delicia Ricardo Adocicados,26,LINQ的智能感应,本例演示了如何查询在Northwind示例数据库中Customers数据表以获得里约热内卢市( Rio de Janeiro )的客户名称。 这段代码与现有的SQL查询方法有明显的区别,其查询操作被集成到编程语言中,使得开发者获得了语言级的支持。以前SQL查询操作是写成一个命令字符串,直到运行该查询命令时才能检查语法错误。而本例中的where语句需要用到Customers数据表中的一个字段,开发者在编程时往往记不住字段的名字。但是因为LINQ集成到语言中,智能感应根据代码中输入的c,就可以自动向开发者显示数据表的所有字段供挑选。,27,1.4 语言集成,语言集成是LINQ的基本部分。其中最显而易见的部分是查询表达式特性。例如前面已经介绍的,我们把lambda表达式构成的查询语句: 简写成查询表达式编写的代码:,Customer Customers = GetCustomers( ); IEnumerableCustomer query = Customers .where ( c = c.Country = = “Italy” ); .OrderBy ( c = c.Name ) .Select ( c = new c.Name, c.City ;,28,语言集成的好处,查询表达式编写的代码: 这样改写后,代码简洁,阅读容易。同时,由于LINQ集成到编程语言(如C#)中,可以在开发者编程时,就对写入的语句实时进行检查并提供智能感应的信息提示。 这种简单的查询表达式检查和引导包括本地类型推断、扩展方法、lambda表达式、对象初始化表达式以及匿名类等。,Customer Customers = GetCustomers( ); var query = from c in Customers where c.Country = = “Italy” orderby c.Name select new c.Name, c.City ;,29,1.4.1 声明性编程,下面的例子展示了SQL查询与等价的LINQ查询程序之间的差别: 采用SQL可编写下列代码: SELECT * FROM Customers WHERE Country = Italy 采用C#的LINQ技术可编写下列代码: public List ItalianCustomers ( Customer Customers ) List result = new List ( ); foreach ( Customer c in Customers ) if ( c.Country = “Italy” ) result.Add ( c ); return result; ,30,上例中的查询语句说明,在SQL查询中,表达的是需要什么,即从客户表中需要查找出那些国家是意大利的客户记录来。而其返回的结果时一个长字符串,还需要大量的后期处理。 在LINQ查询中,表达的是如何得到预期的结果,即专门建立一个列表对象集合List,每当用LINQ语句从字符串数组Customers 中找到一个符合条件的客户名时,就用Add方法把它添加到结果对象集合中。这样的语句语法更规范,结果更可用。 LINQ查询用声明性结构取代了迭代的结构描述对数据的操作让程序员的意图表达的更明确,使得程序更容易阅读和维护,从而提高了开发效率。,31,1.4.2 类型检测,语言集成的另外一个重要部分是类型检测。LINQ操作数据中,经常会遇到不同对象、变量的数据类型不一致问题,这就有必要进行自动类型检测和变量间自动进行必要的类型转换。在.NET编程语言中(如C#和VB),所有的数据都是强类型的,都支持这种类型检测,包括查询的集合和被读取或被返回的实体。这样就保证了诸如智能感知和重构等特性发挥效能。,32,1.4.3 透明跨越不同的类型系统,.NET Framework的数据类型系统与SQL Server的数据类型系统是有区别的,当使用LINQ时,会优先考虑.NET系统,因为它是任何承载LINQ查询的语言都支持的类型系统。可是大部分的数据都保留在关系型数据库中,这样就必须对各种类型的数据进行大量的转换。 LINQ可以自动处理这两类数据类型系统之间的转换,使类型系统中的这种差异几乎对程序员完全透明。,33,跨类型系统的透明转换,.NET编程 语言的数据 类型系统,SQL Server 的数据 类型系统,界面,自动转换,34,1.5 LINQ的实现形式,LINQ是一项覆盖很多数据源的技术,其中有些数据源集成在LINQ实现形式中,而这些实现形式是微软提供的.NET Frame-work 3.5的组成部分,如下图所示: 每个实现形式都通过扩展方法集进行定义,而扩展方法集需要的操作符来操作某一特殊的数据源,并由导入的命名空间控制对这些特性的访问。,LINQ to DataSet,LINQ to SQL,LINQ to Entities,LINQ to Objects,LINQ to XML,LINQ toADO.NET,35,1.5.1 LINQ to Objects,设计LINQ to Objects的目的是操作对象集,对象可以相互关联并形成一个图。从视图的角度来看, LINQ to Objects是LINQ查询默认使用的实现形式。需要包括System.Linq命名空间才能正常使用LINQ to Objects。 LINQ to Objects查询不仅局限于用户生成的数据集合,它还可以查询从操作系统或文件系统中抽取的信息,或者其它类型的信息。下例演示了从文件系统抽取信息的LINQ查询。,36,例子1.5 对从文件系统抽取的信息进行LINQ查询,本例演示如何对指定目录下的所有文件进行LINQ查询,找出所有大于10000字节的文件,并按照这些文件的容量大小排序。 string tempPath = Path.GettempPath ( ); DirectoryInfo dirInfo = new DirectoryInfo ( tempPath ); var query = from f in dirInfo.GetFiles ( ); where f.length 10000 orderby f.length descending select f;,37,LINQ to ADO.NET包括三种不同的、共享操作关系数据必需信息的LINQ实现形式: LINQ to SQL,用于处理.NET中自定义类型与物理表架构间的映射。 LINQ to Entities,很多方面与LINQ to SQL类似,但它不把物理数据库当作持久层使用,而是用概念性的实体数据模型(Entity Data Model, EDM)取代。返回结果是独立于物理数据层的抽象层。 LINQ to DataSet,可实现使用LINQ查询临时独立于物理数据库的内存数据表中的数据。,1.5.2 LINQ to ADO.NET,38,1.5.3 LINQ to XML,LINQ to XML提供了一种操作XML数据的、允许查询和数据操作的、略有区别的语法。而VB 2008在此基础上还提供了一种支持LINQ to XML的特殊类型,即在该语言中包括的XML字面值。这种增强的支持可以简化操作XML数据需要的代码。下面用C#编写的查询可以用VB2008更简洁的方式表示出来: dim book = new XElement ( “Book”, new XAttribute ( “Title”, “Programming LINQ” ); from person in team where person.Role = “Author” select new XElement ( “Author”, person.Name ) );,39,用VB2008编写的查询,用VB2008以更简洁的方式上述C#代码为: Dim book = _ % ,40,本课教材与参考资料,相关网站: / /zh-cn/netframework/,41,本章小结,本章主要介绍了LINQ,并简单介绍了它如何工作,还使用了集成到C#这样的主流编程语言中的统一语法,演示了查询和操作数据源。并且进一步介绍了语言集成带来的优点,包括声明性编程、类型检测以及透明跨越不同的类型系统等。最后还简单介绍了在.NET 3.5中可以使用的LINQ实现形式。,42,How to Contact with Me?,Mobil-Phone:E-mail: QQ: 727940264,增一章 C#语言相关新特性,张一鸣 2011年6月25日,Web开发框架技术初级,44,本章主要内容,本章主要是回顾和深入介绍C#中涉及的LINQ基础知识, 包括泛型、匿名、lambda表达式yield关键字、IEnumerable接口等 。,委托,对象初始化表达式,匿名与匿名方法,Lambda表达式,泛型,扩展方法,枚举量和Yield,查询表达式,45,C#的新特征,对于使用LINQ查询来说,它完全依赖与C#中新增的一些概念和特征,因此可以说,泛型等概念和特征是LINQ技术的基础。本章将系统的介绍这些内容,包括泛型、匿名、lambda表达式、yield关键字、IEnumer-able接口等,为学生完全掌握LINQ技术打好基础。,46,增1.1 代理(委托),C#调用方法时,可以向方法传递参数。这些参数分为按值、按引用或按输出等类型。其中引用实际上就是原来变量即实参的别名,指向实参在内存中的位置,所以在方法中对引用类型参数的修改会导致对实参本身的改变。 类似地,如果把方法也看成数据,通过代理机制把方法赋值给一个变量,也就是把这个方法在内存中的位置赋给变量,则通过这个变量就可以把这个方法传递给其他的方法调用。这种类型的变量就是代理类型的变量。,47,代理(委托)的实质,代理本身是一个类,它封装了一个或多个方法。在内部,一个代理保存方法指针(地址)的对照表,即这个代理类里面的每个方法名和它对应的地址的列表。每个方法指针可以与一个引用实例配对,而该实例是包含实例方法的类实例。 声明代理类型时在方法头前面放上关键字delegate,例如 : public delegate void PrintCallback ( int no);,48,例子增1.1 代理的应用实例分析,本例是文书自动回信的局部功能演示。根据输入的来信人姓名和性别,确定增加“先生”或“女士”的称呼;根据处理来信时间,确定增加“你好”、“上午好”或“下午好”的问候语。这需要编制添加称呼词的两个方法和添加时间问候词的三个方法。为了在主程序中使代码简洁清晰,不用if语句分情况调用不同称呼词和问候语的办法,而是采用两个代理分别表示添加的内容,问候语的区别通过代理的参数来解决。,49,例子增1.1 代理类型的应用,using System; Namespace DemoDelegate1 delegate void myDelegate (string s); /无返回类型的代理,添加问候词 delegate string myDelegateStr (string s, bool man);/有返回类型的代理,添加称呼词 class Program static void show1 (string s) Console.WriteLine ( “你好,0!”,s); static void show2 (string s) Console.WriteLine ( “上午好,0!”,s); static void show3 (string s) Console.WriteLine ( “下午好,0!”,s); static string AddTitle ( string s, bool man ) if ( man ) return string.Format ( “你好,0先生!”,s); else return string.Format ( “你好,0女士!”,s); ,50,例子增1.1 (续),static void Main ( string args ) string name = “林晚荣”; string name2 = “徐芷晴”; myDelegate del1 = new myDelegate(show1); Console.WriteLine ( “.NET代理调用” ); del1 (name); /代理调用,del1指向方法show1 Console.WriteLine ( “*” ); Console.WriteLine ( “多路代理绑定调用” ); del1 += show2; /代理del1在已绑定show1基础上又添加指向show2 del1 += show3; /代理del1在原基础上又添加指向show3 del1 (name); /代理调用,del1指向方法show1、show2、show3 Console.WriteLine ( “n 合并掉show1代理调用” ); del1 -= show1; /代理del1现在仅指向show2、 show3 del1 (name); /代理调用,del1仅指向方法show2和show3 Console.WriteLine ( “*” ); myDelegate del2 = AddTitle; Console.WriteLine ( “返回带类型的绑定调用” ); Console.WriteLine ( del2 ( name, true ) ); Console.WriteLine ( del2 ( name2, false ) ); ,51,例子增1.1 代理的应用实例运行结果,.NET代理调用 你好,林晚荣! * 多路代理绑定调用 你好,林晚荣! 上午好,林晚荣! 下午好,林晚荣! * 合并掉show1代理调用 上午好,林晚荣! 下午好,林晚荣! * 返回类型的代理调用 你好,林晚荣 先生! 你好,徐芷晴 女士!,52,例子增1.2 代理的应用实例分析,本例是对一个有10个元素的整形数组,分别调用三个不同的方法过滤选出其偶数、奇数和大于5的数的子集并显示。为了实现这个目的,一般是分别编写筛选偶数的方法IsEven、筛选奇数的方法IsOdd和筛选大于5的数的方法IsOver5,然后在程序里分别调用它们来实现要求。更简洁的办法是采用代理技术,设计一个代理类型NumPredicate和它的实例对象变量even-Predicate。在主程序每次执行不同的任务时,都是调用同一个代理变量,只是分别给这个代理型变量赋值引用不同的方法。,53,例子增1.2 代理的应用实例分析(续),IsEven、IsOdd和IsOver5这三个方法都接收一个整型参数int并判断是否满足条件,然后返回一个布尔型逻辑值。为了解决对数组全部元素过滤挑选的任务,又设计了一个方法FilterArray,它接受待过滤的数组和代理类型NumPredicate的引用变量作为参数,并按照每次引用变量所指向的方法对数组进行具体的过滤操作。对每次选中的结果调用方法DisplayList全部显示出来。本例中采用了列表结构List作为存放选中数组元素结果的保存结构。,54,例子增1.2 代理类型的应用,using System; using System.Collection.Generic; class Delegates public delegate bool NumPredicate ( int num ); public static void Main ( ) int number = 1,2,3,4,5,6,7,8,9,10 ; NumPredicate evenPredicate = IsEven; Console.WriteLine (”Call Iseven using a delegate variable:0”, evenPredicate ( 4 ); List evenNumbers = FilterArray ( number, evenPredicate ); DisplayList (”Use IsEven to filter even numbers”, evenNumbers); List oddNumbers = FilterArray ( number, IsOdd ); DisplayList (”Use IsOdd to filter odd numbers:”, OddNumbers ); List NumberOver5 = FilterArray ( number, IsOver5 ); DisplayList (”Use IsOver5 to filter numbers over 5:”, NumberOver5 ); /end Main method,55,例子增1.2 (续),private static List FilterArray ( int intAr, NumPredicate pred ) List result = new List ( ); foreach ( int item in intAr ) if ( pred ( item ) ) result.Add ( item ); return result; / end method FilterArray private static bool IsOdd ( int number ) return ( number % 2 = 1 ); / end method IsOdd private static bool IsEven ( int number ) return ( number % 2 = 0 ); / end method IsEven private static bool IsOver5 ( int number ) return ( number 5 ); / end method IsOver5 private static void DisplayList ( string descript, List list ) Console.Write ( descript ); foreach ( int item in list ) Console.Write ( “0 “, item ); Console.WriteLine ( ); / end method DisplayList,56,例子增1.2 代理的应用实例运行结果,Call IsEven using a delegate variable: True Use IsEven to Filter even numbers: 2 4 6 8 10 Use IsOdd to Filter odd numbers: 1 3 5 7 9 Use IsOver5 to Filter numbers over 5 : 6 7 8 9 10,57,增1.2 对象初始化器,Visual Studio C#2008提供了一个新特性对象初始化器(object initializer),它可以创建对象并在同一语句中将其属性初始化。这适用于类没有提供所需要的构造函数的情况。 采用初始化器时,不能写与类同名的构造方法,而是写一个与类同名的初始化器,即原来构造方法名字后面的圆括号“()”被一组花括号“ ”和类里面变量成员的初始值所代替。例如,Time1类的默认构造方法: Time1 time = new Time1 ( ); 采用初始化器时就变成: Time1 time = new Time1 Hour=0, Minute=0, Second=0 ; 采用初始化器时,类里面就不能编写任何构造方法。,58,例子增1.3 Time类的对象初始化器,public class Time private int hour; /023 private int minute; /059 private int second; /059 public void SetTime ( int h, int m, int s ) hour = ( ( h = 0 ,59,例子增1.3 程序代码 (续1),public int Hour /属性Hour get return hour; set hour = ( value = 0 ,60,例子增1.3 程序代码(续2),using System; public class ObjectInitializerTest public static void Main ( string args ) Console.Write ( “Time object created with object initializer “ ); Time time = new Time Hour = 14, Minute = 145, Second = 12 ; Console.Write ( “Standard time 0: “, time.ToString ( ) ); Console.Write ( “Universal time 0: “, time.ToUniversalString ( ) ); Console.Write ( “Time object created with Minute property set “ ); Time anothertime = new Time Minute = 45 ; Console.Write ( “Standard time 0: “, anothertime.ToString ( ) ); Console.Write ( “Universal time 0: “, anothertime.ToUniversalString ( ) ); ,61,例子增1.3 程序运行结果:,Time object created with object initializer Standard time: 2:00:12 PM Universal time: 14:00:12 Time object created with Minute property set Standard time: 12:45:00 AM Universal time: 00:45:00 注意:每个属性名只能在对象初始化器表中出现一次。对象初始化器按照每个参数出现的顺序执行属性的初始化。如果对象初始化器中指定的值无效(如Minute = 0145),则set方法强制设其为0。,62,集合初始化器,如果集合实现了泛型System.Collections.Generic-.ICollections接口,并且指定了T的类型,就可以使用集合初始化器来对整个集合初始化。集合初始化器将对集合中的每个元素调用ICollection.Add(T)方法,从而把该元素添加到集合中。 集合初始化器由一系列包括花括号之间的元素初始化器构成,元素初始化器之间使用逗号进行分割。元素初始化器不能是赋值表达式。,63,例子增1.4 集合初始化器和对象初始化器的符合使用,using System; using System.Collections.Generic; namespace DemoInitislizer class Girlfriend /Demo Object public string Name get; set; public int Age get; set; class Boyfriend /Demo Object public string Name get; set; public int Age get; set; public List Girls get; set; /Set Attribute ,64,例子增1.4 程序代码(续),public class SetInitializerTest public static void Main ( string args ) List gfs1 = new List “Mary”, “Susan”,”Lucy” ; List gfs2 = new List ( ); gfs2.Add ( “Mary” ); gfs2.Add ( “Susan” ); gfs2.Add ( ”Lucy” ); Boy boy = new Boy Name = “Tom”, Age = 24, Girls = new List new Girlfriend Name = “Mary” , Age =23 , new Girlfriend Name = “Susan” , Age =19 , new Girlfriend Name = “Lucy” , Age =21 ; ,65,例子增1.4 程序代码的分析说明,本例中,对于gfs1就是用集合初始化器创建的它等价于gfs2对每一个元素分别调用元素初始化器ICollection.Add(T)方法。 对Boy类的对象boy使用了对象初始化器与集合初始化器的符合使用用一条语句完成了对多个对象和整个集合的初始化。,66,增1.3 匿名类型,匿名类型顾名思义就是没有类的名称,也就是没有类的定义,但是它有类体,可以创建简单类,用于存储数据。 匿名类型声明也称为匿名对象生成表达式,类似于初始化器,其声明的开头是关键字new,然后是成员初始化器列表,放在花括号中。在new后面是不能有类的构造方法名(与类名相同)的。例如: var bob = new Name = “Bob Smith”, Age = 26 ; 声明了一个匿名类对象bob,且其属性Name = “Bob Smith”, Age = 26 。注意这个类没有类名。,67,例子增1.5 使用匿名类的例子,using System; class AnonymousTypes static void Main ( ) var bob = new Name = “Bob Smith”, Age = 37 ; Console.WriteLine (“Bob: ”, bob.ToString ( ) ); var steve = new Name = “Steve Jones”, Age = 26 ; Console.WriteLine (“Steve: ”, steve.ToString ( ) ); Console.WriteLine (“nBob and Steve are 0: ”, ( bob.Equals ( steve ) ? “equal” : “not equal” ) ); var bob2 = new Name = “Bob Smith”, Age = 37 ; Console.WriteLine (“nBob2: ”, bob2.ToString ( ) ); Console.WriteLine (“nBob and Bob2 are 0: ”, ( bob.Equals ( steve ) ? “equal” : “not equal” ) ); /end Main method ,68,Bob: Name = Bob Smith, Age = 37 Steve: Name = Steve Jones, Age = 26 Bob and Steve are not equal Bob2: Name = Bob Smith, Age = 37 Bob and Bob2 are equal 分析:上例中使用了隐式类型局部变量保存对匿名
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 住宅工程竣工验收方案
- 城市公园土建工程施工方案
- 2025云南能源职业技术学院省级产业导师选聘(15人)备考练习试题及答案解析
- 2025辽宁沈阳汽车集团有限公司应届生招聘6人考试参考试题及答案解析
- 2025山西晋中学院第二批招聘博士研究生22人备考练习试题及答案解析
- 施工现场交通与物流管理方案
- 2025浙江温州市人才资源开发有限公司招聘编外工作人员3人考试参考试题及答案解析
- 2025年安庆宿松县建设工程消防安全管理站选调人员8名备考练习题库及答案解析
- 2025年甘肃省天水市清水县第六幼儿园招聘保育员备考练习试题及答案解析
- 光伏系统电池管理与优化方案
- 还款协议示范文本
- 带孩子免责协议书范本
- 苏教一年级《心理健康》教案(完整版)
- 国家职业技术技能标准 4-12-01-01 汽车维修工 人社厅发2018147号
- 学术道德与学术规范
- 气管插管为重患者口腔护理
- 电信入围综合施工组织专题方案
- 强制执行申请书(劳动仲裁)
- 饮料生产中的风味控制与风味优化技术
- 针织服装设计课件
- esd防静电知识培训
评论
0/150
提交评论