新書推薦:
《
中国近现代名家精品——项维仁:工笔侍女作品精选
》
售價:HK$
66.1
《
宋瑞驻村日记(2012-2022)
》
售價:HK$
115.6
《
汗青堂丛书138·帝国的切口:近代中国口岸的冲突与交流(1832-1914)
》
售價:HK$
127.4
《
人世事,几完缺 —— 啊,晚明
》
售價:HK$
115.6
《
樊树志作品:重写明晚史系列(全6册 崇祯传+江南市镇的早期城市化+明史十二讲+图文中国史+万历传+国史十六讲修订版)
》
售價:HK$
498.0
《
真谛全集(共6册)
》
售價:HK$
1156.4
《
敦煌通史:魏晋北朝卷
》
售價:HK$
162.3
《
唯美手编16:知性优雅的编织
》
售價:HK$
54.9
|
編輯推薦: |
学习一种编程语言,基本工夫不外乎是掌握程序语言结构和流程基本控制。除此之外,.NET Framework是未来软件开发的共同平台,而通过Visual Studio开发环境更能直接运用.NET Framework丰富的类库。所以无论使用哪一种语言,都能应用公共语言运行库开发出跨平台的应用程序。本书非常适合对Visual C#语言有兴趣,又想对.NET Framework类库有更多了解的读者,通过本书的学习,将可达到对Visual C#语言的全面认识。
|
內容簡介: |
本书引导使用CC、VB的程序员或者类似语言的开发者迅速转向C#,使用C# 高效地开发基于微软 .NET 网络框架(平台)的各种应用程序。 全书分4篇17章。程序基础篇(第1~4章)以控制台应用程序为主,介绍变量、常数基本数据类型的使用、流程控制的条件选择和循环以及数组和字符串等。对象使用篇(第5~9章)以面向对象为基础来探讨类和对象,提供对象生命周期的构造函数;探讨面向对象程序设计的三大特性,即继承、封装和多态;了解集合的特性等。窗口接口篇(第10~14章)以Windows Form为主,使用工具箱加入控件,包括显示信息的控件、文字编辑控件、具有选择功能的控件、提供互动的控件,以及键盘和鼠标事件的处理等内容。应用篇(第15~17章)介绍ADO.NET组件、LINQ语言的应用以及简易方块游戏的制作。 本书对Visual C#语言进行了全面的介绍,非常适合对Visual C#语言感兴趣、想对.NET Framework类库有更多认识的读者阅读。
|
關於作者: |
李馨,软件工程师,先后参与开发多个大型项目,并编写过几本畅销类开发图书,深受广大读者的好评。
|
目錄:
|
目 录
第1篇 程序基础
第1章 欢迎来到C#的世界 1
1.1 从.NET Framework说起 2
1.1.1 公共语言运行库 2
1.1.2 .NET Framework类库 3
1.1.3 程序的编译 3
1.2 认识Visual Studio 2013 3
1.2.1 Visual Studio 2013的版本 4
1.2.2 启动软件并创建项目 4
1.2.3 解决方案资源管理器窗口 7
1.2.4 项目的打开和关闭 9
1.2.5 操作环境的设置 10
1.3 控制台应用程序 12
1.3.1 认识C#语言 12
1.3.2 程序语句 12
1.3.3 认识命名空间 13
1.3.4 编写程序代码 14
1.3.5 为程序代码加注释 15
1.3.6 让程序适时缩排 16
1.3.7 善用IntelliSense 17
1.3.8 创建并运行程序 18
1.4 重点整理 18
1.5 课后习题 19
第2章 数据与变量 21
2.1 什么是通用类型系统 22
2.1.1 整数类型 22
2.1.2 浮点类型和货币 23
2.1.3 其他数据类型 23
2.2 变量和常数 24
2.2.1 标识符的命名规则 24
2.2.2 关键字 24
2.2.3 声明变量 25
2.2.4 常数 27
2.2.5 枚举类型 29
2.3 控制台应用程序的输入输出语句 31
2.3.1 读取数据 31
2.3.2 输出数据 32
2.3.3 格式化输出 33
2.4 类型转换 34
2.4.1 隐式类型转换 35
2.4.2 显式类型转换 36
2.4.3 用户自定义类型结构 38
2.5 运算符 40
2.5.1 算术运算符 40
2.5.2 赋值运算符 40
2.5.3 关系运算符 41
2.5.4 逻辑运算符 41
2.5.5 运算符的优先级 42
2.6 重点整理 42
2.7 课后习题 43
第3章 流程控制 46
3.1 认识结构化程序 47
3.2 条件选择 47
3.2.1 单一选择 48
3.2.2 双重选择 50
3.2.3 嵌套if 52
3.2.4 多重条件 55
3.3 循环 59
3.3.1 for循环 59
3.3.2 while循环 62
3.3.3 dowhile循环 64
3.3.4 嵌套for 66
3.3.5 其他语句 67
3.4 重点整理 68
3.5 课后习题 69
第4章 数组和字符串 73
4.1 数组 74
4.1.1 一维数组的声明 74
4.1.2 数组元素的存取 76
4.1.3 数组的属性和方法 77
4.2 使用多维数组 81
4.2.1 创建二维数组 81
4.2.2 二维数组初始化 82
4.2.3 不规则数组 84
4.2.4 隐式类型数组 86
4.3 字符和字符串 87
4.3.1 转义字符 87
4.3.2 创建字符串 88
4.3.3 字符串常用方法 89
4.3.4 使用StringBuilder类 93
4.4 重点整理 96
4.5 课后习题 97
第2篇 对象使用
第5章 对象和类 101
5.1 面向对象的基础 102
5.1.1 认识对象 102
5.1.2 提供蓝图的类 102
5.1.3 抽象化概念 103
5.2 使用类 104
5.2.1 定义类 104
5.2.2 实例化对象 105
5.2.3 访问权限 106
5.2.4 定义方法成员 107
5.2.5 类属性和存取器 109
5.3 对象旅程 113
5.3.1 产生构造函数 114
5.3.2 析构函数回收资源 115
5.3.3 使用默认构造函数 116
5.3.4 构造函数的重载 118
5.3.5 对象的初始设置 119
5.4 静态类 121
5.4.1 认识静态类成员 121
5.4.2 静态属性 121
5.4.3 静态类方法 122
5.4.4 静态构造函数 124
5.5 重点整理 126
5.6 课后习题 127
第6章 方法和传递机制 130
6.1 方法是什么 131
6.1.1 系统内建的方法 131
6.1.2 方法的声明 133
6.2 参数的传递机制 137
6.2.1 传值调用 137
6.2.2 传址调用 139
6.3 方法的传递对象 141
6.3.1 以对象为传递目标 141
6.3.2 参数params 142
6.3.3 关键字ref和out的不同 143
6.3.4 更具弹性的命名参数 145
6.3.5 能选择的选择性参数 146
6.4 方法的重载 147
6.5 了解变量的作用域 149
6.6 重点整理 151
6.7 课后习题 152
第7章 继承、多态和接口 155
7.1 了解继承 156
7.1.1 特化和泛化 156
7.1.2 组合关系 157
7.1.3 为什么要有继承机制 157
7.2 单一继承机制 157
7.2.1 继承的存取(或访问) 158
7.2.2 访问权限修饰词protected 162
7.2.3 调用基类成员 165
7.2.4 隐藏基类成员 170
7.3 探讨多态 174
7.3.1 父、子类产生方法重载 174
7.3.2 覆盖基类 175
7.3.3 实现多态 177
7.4 接口和抽象类 181
7.4.1 定义抽象类 181
7.4.2 认识密封类 184
7.4.3 接口的声明 184
7.4.4 如何实现接口 186
7.4.5 实现多个接口 188
7.4.6 接口实现多态 190
7.5 重点整理 192
7.6 课后习题 193
第8章 泛型和集合 196
8.1 浅谈集合 197
8.1.1 认识索引键值 197
8.1.2 使用下标 204
8.1.3 顺序访问集合 206
8.2 创建泛型 208
8.2.1 为什么使用泛型 208
8.2.2 定义泛型 210
8.2.3 产生泛型方法 210
8.3 委托 212
8.4 重点整理 215
8.5 课后习题 216
第9章 错误和异常处理 218
9.1 Visual Studio调试环境 219
9.1.1 错误列表窗口 219
9.1.2 如何调试 220
9.1.3 进入调试程序 223
9.1.4 加入断点 225
9.2 常见的错误 228
9.2.1 语法错误 228
9.2.2 逻辑错误 229
9.3 异常情况的处理 230
9.3.1 认识Exception类 230
9.3.2 简易的异常处理 231
9.3.3 Finally程序块 233
9.3.4 使用throw抛出错误 235
9.4 重点整理 236
9.5 课后习题 237
第3篇 窗口接口
第10章 窗口窗体的运行 239
10.1 Windows 窗体的基本操作 240
10.1.1 创建Windows 窗体项目 240
10.1.2 Windows 窗体的工作环境 241
10.1.3 创建用户界面 245
10.1.4 编写程序代码 250
10.1.5 程序存储的位置 253
10.2 Windows 窗体的运行 254
10.2.1 部分类是什么 254
10.2.2 Main主程序在哪里 255
10.2.3 消息循环 256
10.2.4 在程序中设置属性 257
10.3 使用窗体 260
10.3.1 窗体的属性和方法 260
10.3.2 窗体的事件 262
10.4 MessageBox类 265
10.4.1 显示消息 265
10.4.2 按钮的枚举成员 265
10.4.3 图标的枚举成员 266
10.4.4 DialogResult如何接收 266
10.5 重点整理 270
10.6 课后习题 271
第11章 公共控件 274
11.1 显示信息 275
11.1.1 标签控件 275
11.1.2 超链接控件 280
11.1.3 进度条控件 285
11.1.4 状态栏和面板 285
11.1.5 计时的Timer控件 287
11.1.6 窗体上控件的顺序 290
11.2 文字编辑 292
11.2.1 TextBox控件 292
11.2.2 RichTextBox控件 299
11.2.3 MaskedTextBox控件 307
11.3 与日期有关的控件 308
11.3.1 MonthCalendar控件 308
11.3.2 DateTimePicker控件 314
11.4 具有选择功能的控件 316
11.4.1 单选按钮 316
11.4.2 复选框 321
11.4.3 下拉列表框 321
11.4.4 列表框 327
11.4.5 CheckedListBox控件 328
11.5 重点整理 331
11.6 课后习题 332
第12章 提供互动的控件 337
12.1 文件对话框 338
12.1.1 OpenFileDialog控件 338
12.1.2 SaveFileDialog控件 340
12.1.3 FolderBrowserDialog控件 344
12.2 设置字体与颜色 348
12.2.1 FontDialog控件 349
12.2.2 ColorDialog控件 349
12.3 支持打印的组件 353
12.3.1 PrintDocument控件 353
12.3.2 PrintDialog控件 358
12.3.3 PrintPreviewDialog控件 359
12.3.4 PageSetupDialog控件 363
12.4 菜单 364
12.4.1 MenuStrip控件 365
12.4.2 ContextMenu控件 376
12.4.3 ToolStrip控件 378
12.5 重点整理 380
12.6 课后习题 381
第13章 多文档界面和版面布局 385
13.1 多文档界面 386
13.1.1 认识多文档界面 386
13.1.2 MDI窗体的成员 388
13.1.3 窗体的排列 389
13.2 版面布局 390
13.2.1 FlowLayoutPanel控件 390
13.2.2 TableLayoutPanel控件 392
13.2.3 SplitContainer控件 395
13.3 具有查看功能的控件 395
13.3.1 ImageList控件 395
13.3.2 ListView控件 400
13.3.3 TreeView控件 410
13.4 键盘和鼠标事件 415
13.4.1 认识键盘事件 415
13.4.2 KeyDown和KeyUp事件 415
13.4.3 KeyPress事件 419
13.4.4 认识鼠标事件 420
13.4.5 获取鼠标信息 421
13.4.6 鼠标的拖曳功能 423
13.5 重点整理 426
13.6 课后习题 427
第14章 IO与数据流处理 431
14.1 数据流与System.IO 432
14.2 文件与数据流 432
14.2.1 文件目录 433
14.2.2 文件信息 438
14.2.3 使用File静态类 441
14.3 标准数据流 445
14.3.1 FileStream类 446
14.3.2 StreamWriter写入器 449
14.3.3 StreamReader读取器 449
14.4 重点整理 452
14.5 课后习题 452
第4篇 应用
第15章 ADO.NET组件 455
15.1 数据库基础 456
15.1.1 数据库系统 456
15.1.2 认识关系数据库 457
15.2 认识ADO.NET 457
15.2.1 System.Data命名空间 457
15.2.2 ADO.NET架构 458
15.3 获取数据源 459
15.3.1 生成DataSet 459
15.3.2 查看数据源窗口 464
15.3.3 DataGirdView控件 465
15.4 简易SQL语句 470
15.4.1 使用查询生成器 470
15.4.2 SELECT子句 478
15.4.3 WHERE子句 478
15.4.4 动态查询 479
15.5 用程序代码来提取、存入数据 481
15.5.1 导入相关命名空间 481
15.5.2 用Connection对象连接数据库 482
15.5.3 用Command对象执行SQL语句 483
15.5.4 DataReader显示内容 484
15.5.5 DataAdapter载入数据 486
15.6 重点整理 488
15.7 课后习题 490
第16章 语言集成查询LINQ 494
16.1 LINQ简介 495
16.2 基本的LINQ语法 495
16.2.1 获取数据源 495
16.2.2 创建查询 496
16.2.3 执行查询 496
16.2.4 配合orderby和group子句 498
16.3 LINQ的应用 500
16.3.1 LINQ to Object 500
16.3.2 LINQ to SQL 502
16.4 重点整理 507
16.5 课后习题 508
第17章 简易方块游戏 510
17.1 图形设备接口 511
17.1.1 窗体的坐标系统 511
17.1.2 产生画布 512
17.2 绘制图形 513
17.2.1 认识Graphics类 513
17.2.2 配合画笔绘制线条、几何图形 514
17.2.3 绘制字体 516
17.2.4 Color结构 518
17.3 简易方块游戏 519
17.3.1 游戏界面说明 520
17.3.2 方块的版面 521
17.3.3 方块的组成和移动 521
17.3.4 简易方块游戏相关信息 523
|
內容試閱:
|
序各种程序设计语言都在不断发展、不断完善,C#程序设计语言跟随着.NET Framework技术发展已经超过十年。这个原本模仿音乐上的C?(C调升),从C#.NET到Visual C# 2013一直昂首阔步,向前迈进。下面我们从4个方面来认识Visual C#语言。程序基础篇(第1~4章)这是踏上学习之旅的第一步,焦点在Visual Studio 2013集成开发环境上,以Visual Studio Express版本为主场,从控制台应用程序来浅尝 .NET Framework的魅力。变量和常数的使用、流程控制的条件选择和循环、数组和字符串的使用是本篇的重点内容。对象使用篇(第5~9章)首先以面向对象为基础来探讨类和对象,并提供对象生命周期的构造函数。然后探讨静态类以及传值调用、传址调用。接着探讨面向对象程序设计的3个特性:继承(Inheritance)、封装(Encapsulation)和多态(Polymorphism)。最后由命名空间System.Collections实现IDictionary接口,以了解集合的特性,认识泛型(Generics)的重复使用性、类型安全和高效率的优点。除此之外,还介绍了委托(Delegate)的相关内容,将方法当作变量来传递。窗口接口篇(第10~14章)Windows应用程序主要围绕.NET Framework创建,以窗体(Form)为主,使用工具箱加入控件,最大的优点是不编写任何程序代码也能调整输入输出接口。要设计一个好的Windows应用程序,必须了解控件!这些章节将介绍常用的公共控件、不同用途的对话框、打开多份文件的MDI窗体;探讨System.IO命名空间和数据流的关系;打开文件并读取,创建文件并写入数据,这些不同格式的串流可搭配不同读取器和写入器。应用篇(第15~17章)要以窗体来显示数据库的记录,ADO.NET就是不可或缺的组件。简单介绍它的关系数据库的特色,以Access数据库为模板,配合DataGridView控件显示记录。然后介绍LINQ,它的迷人之处在于数据的查询。最后以一个完整的方块游戏的制作作为结尾。
下载资源获取为了方便读者学习,本书给出了完整的范例程序代码,可从以下地址(注意区分数字和英文字母大小写)下载:
http:pan.baidu.coms1i59ds5f
如果下载有问题,请发送电子邮件至booksaga@126.com,邮件主题设置为求Visual C# 2013从零开始学下载资源。
编 者2017年4月
第8章 泛型和集合
章节重点? 泛型(Generics)类具有重复使用性、类型安全和高效率的优点。? 认识配对集合索引键(key)值(value) 。? 能把方法当作变量进行传递的委托。8.1 浅谈集合一般而言,集合可视为对象容器,用于群组和管理相关的对象。例如,每个Windows 窗体都是一个控件集合,用户可用窗体的Controls进行存取。我们已经学习过数组,乍看之下,集合的结构和数组非常相似(可将数组视为集合的一种),有下标,也能通过For EachNext循环来读取集合中的各表项。一般来说,数组的下标是静态的,经过声明后,数组中的元素不能被删除,若因实际需求要再插入一个数组元素,则只能将数组重新清空,或重设数组大小。为了让索引和表项的处理更具弹性,.NET Framework通过System.Collections命名空间提供了集合类和接口,下面以表8-1来说明。表8-1 System.CollectionCollections(集合) 说 明ICollection接口 定义所有非泛型集合的大小、枚举值和同步方法IDictionary接口 非泛型集合的索引键值组IDictionaryEnumerator接口 枚举非泛型字典的元素IEnumerable接口 公开逐一查看非泛型集合的枚举值IList接口 由下标存取对象的非泛型集合DictionaryEntry结构 定义可设置或提取的字典索引键值组配对ArrayList类 按数组大小动态增加,实现IList接口Hashtable类 根据索引键的哈希程序代码组织而成的索引键值组集合Queue类 对象的先进先出(FIFO)集合SortedList类 索引键值组配对的集合,按索引键排序Stack类 简单非泛型集合,对象组成的后进先出(LIFO)集合使用集合时,其表项会有变动,并且要存取这些集合时必须通过下标(index)来确定表项。一般而言,下标通常以0为起始值。将表项存入集合时,还可以使用对象类型的索引键(key)提取所对应的值(value)。当集合中没有下标或索引键时,必须按序提取表项,例如使用Queue类或Stack类。8.1.1 认识索引键值索引键(key)值(value)是配对的集合,值存入时可以指定对象类型的索引键,以便于使用索引键来提取对应的值。命名空间System.Collections中的Hashtable、SortedList等都是提供索引键值配对的类。使用非泛型来枚举元素进行配对时,可以使用IDictionary、IDictionaryEnumerator接口。先以IDictionary来了解索引键值存取对象的方法,请参考表8-2。表8-2 IDictionary接口成员IDictionary成员 说 明Count 获取ICollection项数Items 获取或设置索引键的指定表项Keys 集合中所有表项的索引键Values 集合中所有表项的值Add方法 将表项加入集合中,须使用keyvalue配对Clear方法 将集合中所有表项删除Contains方法 查询指定表项的key,返回Boolean类型CopyTo方法 从特定的Array索引开始,复制ICollection 表项至ArrayGetEnumerator 返回IDictionary对象的IDictionaryEnumerator对象Remove方法 从集合中删除指定的表项IDictionary接口是索引键值组非泛型集合的基类接口,泛型版本就是位于System. Collections.Generic命名空间的IDictionary。IDictionaryEnumerator接口能处理枚举非泛型字典的元素,相关成员如表8-3所示。表8-3 IDictionaryEnumerator成员IDictionaryEnumerator成员 说 明Current 获取集合中当前的表项Entry 获取当前字典表项的索引键和值Key 获取当前字典表项的索引键Value 获取当前字典表项的值MoveNext 将枚举值往前推至集合中的下一个表项Reset方法 设置枚举值至初始位置,即集合第一个元素(表项)前一般来说,实现IDictionary接口就是要实现表8-2定义的方法。下面以一个简单的查询概念来解说。1 导入命名空间System.Collections。using System.Collections;2 创建一个实现IDictionary接口的类,例如Lexicon类。Public Class Lexicon : IDictionary{ 程序段}3 将索引键值组配对,在构造函数中使用DictionaryEntry结构来指定索引键(key)值(value)配对。延续上述例子,自行定义构造函数。以数组来处理索引键值的配对private DictionaryEntry[] article;private Int32 ItemsInUse = 0; 构造函数 以DictionaryEntry结构来指定配对public LexiconInt32 manyItems {article = new DictionaryEntry[manyItems];}4 实现IDictionary接口的属性和方法。以items属性来说,语法如下:Object this[Object key] { get; set; }● key:要获取或设置的表项的索引键。该语句表示实现接口items属性时,存取器get和set都要实现。public object this[object key]{ get { 判断下标值是否在字典中,若有,则返回其值 Int32 index; if IndexOfKeyDoWorkkey, out index {找到索引键,返回其值return article[index].Value; } else {没有找到索引键return null; } } set { 判断下标值是否在字典中,若有,则更换其值 Int32 index; if IndexOfKeyDoWorkkey, out index { article[index].Value = value; } else {字典中没有发现,以新增方式将索引键值配对 Addkey, value; } }}5 同样,实现Add方法后才能创建Lexicon对象。这里以Add方法加入索引键值,使用Add方法将带有索引键和值的表项加入IDictionary对象,语法如下:void AddObject key, Object value● key:要加入表项的索引键。● value:要加入表项的值。先实现Add方法public void Addobject key, object value{ 如果索引键已经存在,就以新增方式将索引键值配对 if useFreg == article.Length { throw newInvalidOperationException"无法再新建项目"; } article[useFreg] = new DictionaryEntrykey, value;}再以Add方法加入表项IDictionary lex = new Lexicon5;lex.Add"Tomas", 25;lex.Add"Michelle", 27;使用索引键值,再加上下标(index),其数据结构如图8-1所示。图8-1 索引键值的结构由于使用的是DictionaryEntry结构,因此可使用foreach循环来读取表项。foreachDictionaryEntry de in lexlblShow.Text= String.Format"{0}, 年龄 : {1}", _ de.Key, de.Value;DictionaryEntry的对象会存储每个表项的索引键值组,且每个配对必须具有唯一名称。IDictionary接口允许列举所包含的索引键和值,但是不表示任何特定的排列顺序。通常IDictionary接口实现分为3类:只读、固定大小、可变大小。● 只读:IDictionary对象无法修改。● 固定大小:IDictionary对象不允许加入或删除表项,但允许修改现有表项。● 可变大小:IDictionary对象允许加入、删除和修改表项。CH0801A IDictionary接口的Key和Value1 模板为控制台应用程序,项目名称为CH0801A.csproj。在该项目下加入两个类:Lexion(实现IDictionary接口)和enumLexicom(实现IDictionaryEnumerator接口)。Program.cs是Main主程序所在的文件。2 在Lexion.cs中编写的程序代码如下:14 class Lexion : IDictionary15 {16以数组来处理索引键值的配对17public DictionaryEntry[] article;18protected Int32 useFreg = 0;19构造函数 以DictionaryEntry 结构来指定配对值20public LexionInt32 manyItems21{22article = new DictionaryEntry[manyItems];23}24删除指定表项25public void Removeobject key26{27if key == null28{29 throw new ArgumentNullException"key";30}31尝试从DictionaryEntry数组中寻找索引键key32Int32 index;33if IndexOfKeyDoWorkkey, out index34{35 如果找到了,就让所有表项向上移动36 Array.Copyarticle, index 1, article, index,37 useFreg - index - 1;38 useFreg--;39}40else 即使没有,也要返回结果41 Console.WriteLine"找不到要删除的名称";42}43 ...省略程序代码44 }3 在enumLexicom.cs中编写的程序代码如下:13 class enumLexicom : IDictionaryEnumerator14 {15IDictionaryEnumerator枚举非泛型字典的元素16DictionaryEntry[] article;17Int32 index = -1;18构造函数19public enumLexicomLexion lc20{21article = new DictionaryEntry[lc.Count];22以复制方式将Lexicon对象的索引键值配对23Array.Copylc.article, 0, article, 0, lc.Count;24}25返回当前的表项26public Object Current27{28get{VerityEnumIndex; return article[index];}29}30返回当前字典表项的索引键值31public DictionaryEntry Entry32{33get{return DictionaryEntryCurrent;}34}35...省略程序代码36 }4 在Main主程序中编写的程序代码如下:11 static void Mainstring[] args12 {13int peop = 4;14根据IDictionary接口实现类Lexion所创建的对象15IDictionary lex = new Lexionpeop;16以Add新增4位成员17whilepeop = 118{19Console.Write"输入名字:";20string title = Console.ReadLine;21Console.Write"输入分数:";22int score = int.ParseConsole.ReadLine;23lex.Addtitle, score;24peop--;25}26Console.WriteLine"学生人数 = {0}" , lex.Count;27Console.WriteLine"Matthew是否为学生?{0}, 分数 : {1} " ,28lex.Contains"Matthew", lex["Matthew"];29显示索引键值配对30foreach DictionaryEntry de in lex31{32Console.WriteLine"{0}, 分数 : {1}",33 de.Key, de.Value;34}35删除某个表项36lex.Remove"Naomi";37显示学生名称索引键38foreachstring title in lex.Keys39Console.Write"{0} ", title;40显示学生年龄41foreachint score in lex.Values42Console.Write"{0,3}", score;43 }运行:按Ctrl F5组合键运行程序,打开命令提示符窗口,按提示输入名字和分数,显示图8-2所示的运行结果。程序说明? 创建一个简易的查询表,以Lexion类实现IDictionary接口创建查询表,以enumLexicom类实现IDictionaryEnumerator接口维护查询表的正确性。Lexion.cs程序(实现IDictionary接口)? 第26~42行:Lexion类实现Remove方法,根据索引键(key)删除指定表项。? 第27~30行:如果找不到指定的表项会以throw语句抛出异常。? 第33~41行:如果找到表项并删除了,就以Array类的Copy方法把表项向上移动。enumLexicom.cs程序(实现IDictionaryEnumerator接口)? 第19~24行:构造函数。当查询表有变动时,配合Array类的Copy方法来重新创建一个查询表。? 第26~29行:属性Current按下标值来获取当前的表项。? 第31~34行:属性Entry按Current返回值读取当前表项的索引键值。Main主程序? 第15行:根据IDictionary接口实现类Lexion所创建的lex对象。? 第17~25行:以while循环来创建名字分数的数据,再以Add方法加入查询表中。? 第26~28行:以属性Count来统计输入学生数,Contains来对比指定表项Matthew,若查询到,则返回True结果以及Matthew的分数。? 第30~34行:使用DictionaryEntry结构,并以foreach循环来读取输入的索引键值。? 第36~42行:以Remove方法来删除指定表项,再重新读取学生的名字和分数。8.1.2 使用下标使用集合表项避免不了新增和删除,这些集合表项的存取就得使用下标(index)。下标是介于0或1和集合表项数目之间的整数。通过命名空间System.Collections的IList接口可以了解以下标存取对象的属性和方法,可参考表8-4。表8-4 IList接口的成员IList接口成员 说 明Count 获取集合表项数Item 获取或设置集合表项IsFixedSize 集合是否为固定大小IsReadOnly 集合是否为只读Add方法 将表项加入集合中Clear方法 将所有表项删除Contains方法 查询的指定表项是否在集合中,返回Boolean类型IndexOf方法 查询指定表项的下标值,返回Integer类型,-1表示不存在Insert方法 将表项插入到指定的下标位置Remove方法 从集合中删除指定的表项RemoveAt 从集合中删除指定下标值对应的表项ArrayList实现System.Collection的IList接口,会根据数组列表大小动态增加容量,提供新增、插入、删除元素的方法,比数组更具弹性。随着元素的逐渐加入,ArrayList会视需要重新配置可以保存的表项数。以构造函数来指定其容量的语句如下:ArrayLIst arrayList = new ArrayList[6];arrayList.Capacity[5];若要降低容量,则可调用TrimToSize或设置Capacity属性。由于ArrayList比Array更具弹性,因此使用时有所区别,可参照表8-5的说明。表8-5 Array和ArrayList的比较异 同 点 Array ArrayList使用类型时 声明时要指定类型 可以是任何对象能否扩充容量 自动扩充容量数组元素 不能动态改变 由Insert新增,由Remove删除性能 较好 比较差使用ArrayList类的Add方法加入数据时会加到结尾处,而且允许加入不同类型的表项。ArrayList arrayList = new ArrayLIst;arrayList.Add"Tomas";arrayList.Add25;arrayList.Addfalse;ArrayList arrayList2 = new ArrayLIst {"Tomas", 25, false};CH0801B 使用ArrayList类1 设置模板为控制台应用程序、项目名称为CH0801B.csproj。2 Main主程序编写的程序代码如下:14 static void Mainstring[] args15 {16ArrayList student = new ArrayList;17DateTime date1 = new DateTime1992, 3, 5;18以Add方法加入表项19student.Add"Michelle";20student.Adddate1.ToShortDateString;21student.Add"Doris";22student.Add33;23itemPrint"列出结果:", student;24 若有某个表项,则删除25if student.Containsdate1.ToShortDateString26{27student.Removedate1.ToShortDateString;28student.RemoveAt2;指定下标位置删除29itemPrint"经过删除后:", student;30}31else32itemPrint"不存在!", student;33新建表项34Int32 index = 0;35student.Insertindex, "Tomas";36student.Add"Stephen";37itemPrint"插入新表项:", student;38student.Sort;39itemPrint"经过排序:", student;40 }41 for循环读取表项42 public static void itemPrintstring str,43ArrayList arrList44 {45Int32 index = 0;46Console.Write"{0}", str;47foreach Object obj in arrList48{49Console.Write"[{0}]-{1, -10}", index, obj;50index;51}52Console.WriteLine;53 }运行:按Ctrl F5组合键运行此程序,打开命令提示符窗口,运行结果如图8-3所示。图8-3 范例CH0801B的运行结果程序说明? 第16~22行:创建ArrayList类的对象student,以Add方法加入类型不同的表项,调用itemPrint方法传入参数值,显示结果。? 第25~32行:以if来判断要删除的表项是否存在。以Remove指定表项,以RemoveAt指定下标值位置进行删除。? 第35~38行:以Add方法加入新表项,或者以Insert指定下标位置加入表项,最后以Sort方法进行排序。? 第42~53行:itemPrint方法接收参数值后,以foreach循环来读取表项内容并输出结果。8.1.3 顺序访问集合在集合表项中有两种处理数据的方式,即先进先出、后进先出。先进先出的Queue下面对其中的类Queue(队列)来做介绍。Queue采用FIFO(First In First Out,先进先出),也就是第一个加入的表项会第一个从集合中删除。Queue的属性和方法可参照表8-6的说明。表8-6 Queue类的成员Queue成员 说 明Count 获取队列的表项个数Clear 从队列中删除所有对象Contains 判断表项是否在队列中CopyTo 指定数组下标,将表项复制到现有的一维Array(数组)中Dequeue 返回队列前端的对象并删除(续表)Queue成员 说 明Enqueue 将对象加入到队列末端Equals 判断指定的对象和当前的对象是否相等Peek 返回队列第一个对象TrimToSize 设置队列中的实际表项个数队列处理数据的方式就如同排队买票一般,最前面的人可以第一个购得票,等待在最后的人必须等待前方的人购完票后才能购票。CH0801C 使用Queue类1 设置模板为控制台应用程序、项目名称为CH0801C.csproj。2 在Main主程序中编写的程序代码如下:14 static void Mainstring[] args15 {16Int32 one, index = 6;17创建队列对象18Queue fruit = new Queue;19string[] name = {"Strawberry", "Watermelon", "Apple",20"Orange", "Banana", "Mango"};21for int ct = 0; ct 027{28one = index - fruit.Count 1;29Console.WriteLine"第{0}种水果 - {1}", one,30 fruit.Peek;31}32itemPrint"水果", fruit;33Dequeue删除最前端的表项34if fruit.Count 035{36one = index - fruit.Count 1;37Console.WriteLine"删除第{0}种水果 - {1}", one,38 fruit.Dequeue;39}40itemPrint"少了一种水果之后", fruit;运行:按Ctrl F5组合键运行此程序,打开命令提示符窗口,运行结果如图8-4所示。程序说明? 创建Queue类的对象fruit,以Peek方法显示第一个表项,以Enqueue方法将表项从尾端加入,以Dequeue方法从最前端删除表项。? 第18~24行:创建Queue对象fruit,并以for循环配合Enqueue方法将数组name加到队列中。? 第26~31行:先以Count属性进行判断,如果表项存在,就以Peek显示第一个表项。? 第34~39行:以Dequeue方法删除第一个表项。后进先出的Stack可以将Stack(堆栈)类数据的进出想象成叠盘子,从底部向上堆叠,想要获取底部的盘子,只有从上方把后加进来的盘子拿走才有可能,这就形成了LIFO(Last In First Out,后进先出)的方式。先使用Push方法将表项加到上方,再使用Pop方法弹出(移除)最上方的表项。Stack常用成员如表8-7所示。表8-7 Stack成员Stack成员 说 明Count 获取堆栈的表项个数Clear 从堆栈中删除所有表项Peek 返回堆栈最上端的表项Push 将表项加到堆栈的最上方Pop 将堆栈最上方的表项删除8.2 创建泛型泛型类和方法将重复使用性、类型安全和高效率结合在一起,提供了非泛型的类和方法无法提供的功能。泛型最常搭配的是集合类及其方法的使用。.NET Framework的类库提供了命名空间System.Collections.Generic,其中包含多个以泛型为基础的集合类。● 使用泛型以优化程序代码的重复使用性、类型安全性和高效率。● 泛型最常见的用法是创建集合类。8.2.1 为什么使用泛型或许大家会很奇怪,为什么要使用泛型呢?下面以简单例子来说明。11 static void Mainstring[] args12 {13int[] one ={11,12,13,14,15};第一个数组14string[] two = {"Eric", "Andy", "John"};第二个数组15ShowMessage1one;读取数组一16ShowMessage2two;读取数组二17 }18 读取数组一19 private static void ShowMessage1int[] arrData20 {21foreachint item in arrData22Console.Write"{0, 3}", item;23Console.WriteLine"\n";24 }25 读取数组二26 private static void ShowMessage2string[] arrData27 {28foreachstring item in arrData29Console.Write"{0, 6}", item;30Console.WriteLine"\n";31 }● 第13、14行:声明两个数组,类型不同,长度也不一样。● 第19~24行:foreach循环读取整数类型的数组。● 第26~31行:另一个foreach循环读取字符串类型的数组。● 问题:如果有更多不同类型的数组要处理,是不是要编写更多的程序代码呢?如果将ShowMessage方法修改如下:19 读取数组 使用泛型20 private static void ShowMessageT[] arrData21 {22foreachT item in arrData23Console.Write"{0} ", item;24Console.WriteLine"\n";25 }? 第20行:在ShowMessage方法后加入(尖括号)内有类型参数T,用来取代原有的int或string类型,进一步来说,可以代表任何数据类型。? 第22行:以foreach循环读取时,原来的intstring类型就被T取代。当arrData接收的是int类型时,foreach循环就读取整数类型;当arrData数组接收的是string时,就以字符串来处理。如此一来,不管有多少数组,使用泛型的写法都会大大改进原有的问题,这也是泛型的魅力所在!8.2.2 定义泛型泛型能以未定类型的变量来声明类、接口或方法。使用new来实例化对象可以指定变量的类型。定义泛型后,不用为不同的变量类型编写相同的程序代码,可以提高类型安全,让不同的类型做相同的事,让对象彼此共享方法成员,达到重复使用性。双效合一后,能让程序的效率提高!定义泛型的语法如下:class 泛型名称 { 程序段}● 定义泛型以class开头,接着是泛型名称。● 尖括号内放入类型参数(Type parameter)列表,一般使用大写字母T来表示。● 尖括号内的每个变量代表一个数据类型名称,参数间以逗号隔开。● 定义泛型时,先使用类型参数进行声明,表示此类型数据是未定的。下面是一个简单的泛型语句。class GenericList 只有一个变量{ Console.WriteLine"\nRunning!";}8.2.3 产生泛型方法定义泛型后要进一步定义公有的方法成员。以泛型类的成员来说,类型参数是声明泛型类型的变量,会以特定类型的替代符号(Placeholder)来指定,其后相关的数据都适用,声明方法如下:public void 方法名称T 变量名称{ 程序段}实际的方法成员语句如下:public void ShowMessageT output Console.WriteLine"\n{0} is Running!", output;}有了泛型和成员方法,就可以使用new运算符创建不同数据类型的实体对象了,语法如下:泛型类名称 对象名称 = new 泛型类名称;延续前一个范例的概念,创建一个泛型类,可以输入string、int类型的数据来存放,再以foreach循环进行输出。CH0802C 使用泛型类1 设置模板为控制台应用程序、项目名称为CH0802C.csproj,再加入一个类Student.cs。2 在Student.cs类中的程序代码如下:11 class Student12 {13private int index;数组下标值14private T[] items = new T[5];存储6个数组元素15将数据放入数组,string、int类型16public void StoreArrayT arrData17{18if index manyStudent = new Student;15manyStudent.StoreArray"Tomas";16manyStudent.StoreArray"John";17manyStudent.StoreArray"Eric";18manyStudent.StoreArray"Steven";19manyStudent.StoreArray"Mark";20manyStudent.ShowMessage;21创建泛型类对象 成绩22Student Score = new Student;23Score.StoreArray78;24Score.StoreArray83;25Score.StoreArray48;26Score.StoreArray92;27Score.StoreArray65;28Score.ShowMessage;29 }运行:按Ctrl F5键运行此程序,打开命令提示符窗口,运行结果如图8-5所示。图8-5 范例CH0802C的运行结果程序说明Student.cs程序? 创建泛型类Student,含有T类型参数,以不同类型来创建数据。? 第14行:创建含有T类型参数的数组,可以存放6个元素。? 第16~23行:StoreArray使用T类型参数来接收输入的数组元素,使用for循环来读取输入的数组元素。? 第25~33行:ShowMessage方法以foreach循环来输出数组元素。Main主程序? 第14行:以泛型类来创建一个对象,表示以字符串类型为主。? 第22行:以泛型类来创建一个对象,表示以整数类型为主。? 讨论:泛型类Student代表它不是真的类型,比较像是类型的蓝图。使用时必须借助尖括号来指定类型变量,让编译程序可以辨认它的类型。8.3 委托当程序中调用方法时会进行变量的传递,它通常有所限制,只能使用常数、变量、对象或数组,但是方法无法以变量来传递!委托(Delegate)就是把方法视为变量来传递。委托是一种类型,代表具有特定参数列表和返回类型的方法引用。也就是在程序中调用方法时,可以将其实例通过委托实例执行(Invoke,或调用)方法。Windows窗体的控件触发的事件处理程序就是以委托方式来处理的,将方法当作变量传递给其他方法。委托类型派生自 .NET Framework中的Delegate类。委托类型是密封的,不能作为其他类型的派生来源,且不能从Delegate派生自定义类。因为实现的实例是委托对象,所以它可以作为参数传递或赋值给属性。如此一来,方法才能以参数方式接受委托,并进行委托的调用,这称为异步返回调用,是较长进程完成时通知调用端的常用方法。所以要定义委托时是以关键字delegate来声明一个方法,其语法如下:delegate 数据类型 委托名称变量列表;● 委托名称:用来指定方法的委托名称。● 数据类型:参考方法的返回值类型。定义委托名称后,还要声明一个委托对象,用来传递方法。public delegate bool SpeculationInt32 numerical;Speculation evenPredicate;声明委托变量evenPredicate = new SpeculationIsEven;IsEven方法最后还要定义一个委托方法,将委托对象以变量来传递。private static List ArrayPercolateint[] intArray, Speculation special{ . . . }CH0803 使用委托1 设置模板为控制台应用程序、项目名称为CH0803.csproj。2 在Main主程序块中编写的程序代码如下:13 1.定义委托方法,含有一个变量数值14 public delegate bool SpeculationInt32 numerical;15 static void Mainstring[] args16 {17创建一个数组18Int32[] figures =19{11, 12, 13, 14, 15, 16, 17, 18, 19, 20};20Speculation evenPredicate;声明委托变量212.委托变量要调用方法22evenPredicate = new SpeculationIsEven;2324List evenNumbers = ArrayPercolatefigures,25evenPredicate;26showMessage"筛选后的偶数:", evenNumbers;2728List oddNumbers = ArrayPercolatefigures,29IsOdd;30showMessage"筛选后的奇数:", oddNumbers;3132List numberDivide3 = ArrayPercolatefigures,33IsDivide3;34showMessage"能被3整除的数值:", numberDivide3;35Console.Read;36 }37 找出偶数38 private static bool IsEvenInt32 numerical39 {40return numerical % 2 == 0;余数为041 }42 找出奇数43 private static bool IsOddint numerical44 {45return numerical % 2 == 1;46 }47 被3整除的数值48 private static bool IsDivide3int numerical49 {50return numerical % 3 == 0;51 }52 读取List元素53 private static void showMessagestring str,54Listlist{55Console.WriteLinestr;56读取数组元素57foreachint item in list58Console.Write"{0,3}", item;59Console.WriteLine;60 }61 3.委托方法筛选数组元素 根据传入的数组元素重新创建数组62 private static List ArrayPercolateint[] intArray,63Speculation special64 {65List result = new List;66读取数组元素67foreachint item in intArray68{69ifspecialitem确认是委托方法70 result.Additem;71}72return result;73 }运行:按Ctrl F5键来运行此程序,打开命令提示符窗口,运行结果如图8-6所示。程序说明? 第14行:声明委托名称Speculation,含有一个整数类型的变量。? 第20~23行:声明委托对象所要调用的方法,表示IsEven、IsOdd、IsDivide3三个方法都要传入Int32类型的整数,并返回布尔值。? 第24~26行:将数组的数值调用委托方法ArrayPercolate传入委托对象evenPredicate进行筛选,所得结果再以泛型List类来创建含有偶数值的新数组。? 第28~30行:将数组的数值调用委托方法ArrayPercolate,将IsOdd方法当作变量来传递并筛选出奇数,所得结果再以泛型List类来创建含有奇数值的新数组。? 第32~34行:将数组的数值调用委托方法ArrayPercolate,将IsDivide3方法当作变量来筛选出能被3整除的数值,所得结果再以泛型List来创建数组。? 第38~41行:IsEven方法,将接收的数值除以2,若余数为零,则表示是偶数。? 第53~60行:showMessage方法,按List所创建的数组大小以for循环来读取并输出数组元素。? 第62~73行:委托所定义的方法ArrayPercolate,传入figures数组,根据委托对象所传递的方法来决定它是否是List数组所要的元素,经由if语句进行判断,如果是,就以Add方法把它加到List数组中。8.4 重点整理? 集合可视为对象容器,用于群组和管理相关的对象。.NET Framework通过System.Collections命名空间提供了集合类和接口。? 索引键(key)值(value)是配对的集合,值存入时可以指定对象类型的索引键,便于使用时能以索引键提取对应的值。? ArrayList实现System.Collection的IList接口,会根据数组列表的大小动态增加容量,提供新增、插入、删除元素的方法,比数组更具弹性。? 在IDictionary接口中,属性Keys获取集合中所有表项的索引键,Values获取集合中所有表项的值。Add方法将表项加入集合中,需使用keyvalue进行配对。? 使用Queue(队列)时,Enqueue方法将对象加入到队列末端,Dequeue方法会返回队列前端的对象并将其从队列中删除。? 使用Stack(堆栈)时,Peek方法返回堆栈最上端的表项,Push方法用于把表项加到堆栈的最上方,Pop方法则是把堆栈最上方的表项弹出并删除。? 委托就是把方法视为变量来传递。委托是一种类型,代表具有特定参数列表和返回类型的方法引用。也就是在程序中调用方法时,可以将其实例通过委托实例执行(Invoke,或调用)方法。它派生自 .NET Framework中的Delegate类。委托类型是密封的,不能作为其他类型的派生来源,且不能从Delegate派生自定义类。8.5 课后习题一、选择题(1)哪一个类可以实现IList接口?()A. Array类B. ArrayList类C. Stack类 D. Queue类(2)哪一个类的表项采用先进先出(FIFO)的方式?()A. Array类B. ArrayList类C. Stack类 D. Queue类(3)哪一个类的表项采用后进先出(LIFO)的方式?()A. Array类B. ArrayList类C. Stack类 D. Queue类(4)在数组上使用ArrayList类,如果要重新设置数组的大小,要用哪一个属性?()A. CapacityB. Count C. ItemD. IsReadOnly(5)对于委托的描述,哪一个有误?()A. 派生自.NET Framework中的Delegate类B. 能作为其他类型的派生来源C. 把方法视为变量来传递D. 具有特定参数列表和返回类型的方法引用二、填空题(1)在IDictionary接口中,属性________获取集合中所有表项的索引键,属性____________获取集合中所有表项的值,方法________将表项加入集合中。(2)使用Queue(队列)时,____________方法会返回队列前端的对象并将其从队列中删除,____________方法将对象加入到队列末端。(3)使用Stack(堆栈)时,________方法返回堆栈最上端的表项,________方法把表项加到堆栈的最上方,________方法则是把堆栈最上方的表项弹出并删除。三、实践题(1)IDictionary界面的实现分为3类,请简答之。(2)使用委托的概念,设计一个能计算三角形和矩形面积的委托对象,运行结果可参照图8-7。习题答案一、选择题(1)B(2)D(3)C(4)A(5)B 二、填空题(1)Keys Values Add(2)Dequeue Enqueue(3)Peek Push Pop三、实践题(1)● 只读:IDictionary对象无法修改。● 固定大小:IDictionary对象不允许加入或删除表项,但允许修改现有表项。● 可变大小:IDictionary对象允许加入、删除和修改表项。(2)略
|
|