出版日期:2011年06月
ISBN:9787115251831
[十位:7115251835]
页数:469
定价:¥69.00
店铺售价:¥23.70
(为您节省:¥45.30)
店铺库存:7
本
正在处理购买信息,请稍候……
我要买:
本
* 如何购买
联系店主:
15974791540
-
100分
满分
确认收货后30天未评价,系统默认好评!
[2024-12-28 19:14:28]
雷**
武汉市
-
100分
满分
确认收货后30天未评价,系统默认好评!
[2024-12-28 18:46:07]
雷**
武汉市
-
100分
满分
确认收货后30天未评价,系统默认好评!
[2024-12-28 18:10:48]
杜**
新乡市
-
100分
满分
确认收货后30天未评价,系统默认好评!
[2024-12-28 09:46:20]
彭**
重庆市
-
100分
满分
确认收货后30天未评价,系统默认好评!
[2024-12-27 16:06:24]
李**
南宁市
《C# 4.0图解教程》内容提要:
作为.NET平台上*主要的编程语言,C#在不断地改进和完善,功能越来越强大。当然,复杂性也随之增加,令很多初学者不得其门而入。
如 何才能让更多人轻松地学习和掌握C#呢?本书作者总结了自己数十年软件开发和教学培训经验,创造了一种全新的可视化叙述方式。在书中,他通过大量图、表和 代码,与简洁的文字**结合,从底层运行原理的角度阐释了*新版C#和.NET的所有基本特性,并讲解了LINQ、异步编程和反射等**特性,使原本非常 复杂的知识点变得简单明了、清晰透彻,让人耳目一新,大?降低了学习难度。阅读本书时,你仿佛置身于课堂,看着一位经验丰富的老师拿着粉笔画图演示,娓娓 道来。本书原版一经问世,就赢得广泛好评,被誉为C#入门经典著作,不仅适合自学,也是课堂教学的**。
《C# 4.0图解教程》图书目录:
第1 章 C#和NET 框架 1
1.1 在NET 之前 1
1.1.1 20 世纪90 年代后期的Windows 编程 1
1.1.2 下一代平台服务的目标 2
1.2 进入Microsoft NET 2
1.2.1 NET 框架的组成 2
1.2.2 大大改进的编程环境 3
1.3 编译成CIL 5
1.4 编译成本机代码并执行 5
1.5 CLR 6
1.6 CLI 7
1.7 缩写回顾 8
第2章 C#编程概述 9
2.1 一个简单的C#程序 9
2.2 标识符和关键字 11
2.2.1 命名约定 11
2.2.2 关键字 12
2.3 Main:程序的起始点 12
2.4 空白 13
2.5 语句 13
2.5.1 简单语句 13
2.5.2 块 14
2.6 从程序中输出文本 14
2.6.1 Write ?14
2.6.2 WriteLine 15
2.6.3 格式字符串 15
2.6.4 多重标记和值 16
2.7 注释 16
2.7.1 关于注释的补充 17
2.7.2 文档注释 17
2.7.3 注释类型总结 18
第3 章 类型、存储和变量 19
3.1 C#程序是一组类型声明 19
3.2 类型是一种模板 20
3.3 实例化类型 20
3.4 数据成员和函数成员 21
3.5 预定义类型 21
3.6 用户定义类型 23
3.7 栈和堆 24
3.7.1 栈 24
3.7.2 堆 25
3.8 值类型和引用类型 25
3.8.1 存储引用类型对象的成员 26
3.8.2 C#类型的分类 27
3.9 变量 27
3.9.1 变量声明 27
3.9.2 多重变量声明 29
3.9.3 使用变量的值 29
3.10 静态类型和dynamic 关键字 29
3.11 可空类型 30
3.11.1 创建可空类型 30
3.11.2 为可空类型赋值 31
第4 章 类:基础 32
4.1 类的概述 32
4.2 程序和类:一个快速的示例 33
4.3 声明类 33
4.4 类成员 34
4.4.1 字段 34
4.4.2 显式和隐式字段初始化 35
4.4.3 声明多个字段 36
4.4.4 方法 36
4.5 创建变量和类的实例 37
4.6 为数据分配内存 37
4.7 实例成员 38
4.8 访问修饰符 39
4.9 从类的内部访问成员 41
4.10 从类的外部访问成员 42
4.11 综合应用 43
第5 章 方法 45
5.1 方法的结构 45
5.2 本地变量 47
5.2.1 类型推断和var 关键字 47
5.2.2 嵌套块中的本地变量 48
5.3 本地常量 49
5.4 方法调用 51
5.5 返回值 52
5.6 参数 54
5.6.1 形参 54
5.6.2 实参 55
5.6.3 带位置输入参数的方法示例 55
5.7 值参数 56
5.8 引用参数 58
5.9 输出参数 60
5.10 参数数组 62
5.10.1 方法调用 63
5.10.2 数组作实参 65
5.11 参数类型总结 66
5.12 方法重载 66
5.13 命名参数 67
5.14 可选参数 68
5.15 栈帧 71
5.16 递归 72
第6 章 类进阶 74
6.1 类成员 74
6.2 实例类成员 76
6.3 静态字段 76
6.4 从类的外部访问静态成员 77
6.4.1 静态字段示例 77
6.4.2 静态成员的生存期 78
6.5 静态函数成员 79
6.6 其他静态类成员类型 80
6.7 成员常量 80
6.8 属性 82
6.8.1 属性声明和访问器 83
6.8.2 属性示例 83
6.8.3 使用属性 84
6.8.4 属性和关联字段 85
6.8.5 执行其他计算 86
6.8.6 只读和只写属性 87
6.8.7 计算只读属性示例 87
6.8.8 属性和数据库示例 88
6.8.9 属性vs公共字段 88
6.8.10 自动实现属性 89
6.8.11 静态属性 89
6.9 实例构造函数 90
6.9.1 带参数的构造函数 91
6.9.2 默认构造函数 92
6.10 静态构造函数 93
6.10.1 静态构造函数示例 93
6.10.2 构造函数的可访问性 94
6.11 对象初始化列表 94
6.12 析构函数 95
6.12.1 调用析构函数 96
6.12.2 标准清理模式 98
6.13 比较构造函数和析构函数 99
6.14 readonly 修饰符 99
6.15 this 关键字 100
6.16 索引 101
6.16.1 什么是索引 102
6.16.2 索引和属性 102
6.16.3 声明索引 103
6.16.4 索引的set 访问器 104
6.16.5 索引的get 访问器 104
6.16.6 关于索引的补充 105
6.16.7 为Employee 示例声明索引 105
6.16.8 另一个索引示例 106
6.16.9 索引重载 107
6.17 访问器的访问修饰符 107
6.18 分部类和分部类型 109
第7 章 类和继承 12
7.1 类继承 112
7.2 访问继承的成员 113
7.3 隐藏基类的成员 115
7.4 基类访问 116
7.5 使用基类的引用 117
7.5.1 虚方法和覆写方法 119
7.5.2 覆写标记为override 的方法 120
7.5.3 覆盖其他成员类型 123
7.6 构造函数的执行 124
7.6.1 构造函数初始化语句 125
7.6.2 类访问修饰符 127
7.7 程序集间的继承 128
7.8 成员访问修饰符 129
7.8.1 访问成员的区域 130
7.8.2 公有成员的可访问性 131
7.8.3 私有成员的可访问性 131
7.8.4 受保护成员的可访问性 132
7.8.5 内部成员的可访问性 132
7.8.6 受保护内部成员的可访问性 132
7.8.7 成员访问修饰符的总结 133
7.9 抽象成员 133
7.10 抽象类 134
7.10.1 抽象类和抽象方法的示例 135
7.10.2 抽象类的另一个例子 136
7.11 密封类 137
7.12 静态类 137
7.13 扩展方法 138
第8 章 表达式和运算符 142
8.1 表达式 142
8.2 字面量 143
8.3 整数字面量? 144
8.4 字符字面量 145
8.5 字符串字面量 146
8.6 求值顺序 147
8.6.1 优先级 148
8.6.2 结合性 148
8.7 简单算术运算符 149
8.8 求余运算符 149
8.9 关系比较运算符和相等比较运算符 150
8.10 递增运算符和递减运算符 152
8.11 条件逻辑运算符 153
8.12 逻辑运算符 154
8.13 移位运算符 155
8.14 赋值运算符 157
8.15 条件运算符 158
8.16 一元算术运算符 159
8.17 用户定义类型转换 160
8.18 运算符重载 162
8.18.1 运算符重载的限制 163
8.18.2 运算符重载的示例 164
8.19 typeof 运算符 165
8.20 其他运算符 166
第9 章 语句 167
9.1 什么是语句 167
9.2 表达式语句 168
9.3 控制流语句 169
9.4 if 语句 169
9.5 if…else ?句 170
9.6 switch 语句 171
9.6.1 分支示例 172
9.6.2 switch 语句的补充 173
9.6.3 switch 标签 174
9.7 while 循环 174
9.8 do 循环 175
9.9 for 循环 176
9.9.1 for 语句中变量的有效范围 177
9.9.2 初始化语句和迭代表达式中的多表达式 178
9.10 跳转语句 178
9.11 break 语句 178
9.12 continue 语句 179
9.13 标签语句 180
9.13.1 标签 180
9.13.2 标签语句的范围 180
9.14 goto 语句 181
9.15 using 语句 182
9.15.1 资源的包装使用 183
9.15.2 using 语句的示例 183
9.15.3 多个资源和嵌套 184
9.15.4 using 语句的另一种形式 185
9.16 其他语句 186
第10 章 命名空间和程序集 187
10.1 引用其他程序集 187
10.2 命名空间 191
10.2.1 命名空间名称 194
10.2.2 命名空间的补充 194
10.2.3 命名空间跨文件伸展 195
10.2.4 嵌套命名空间 195
10.3 using 指令 196
10.31 using 命名空间指令 196
10.32 using 别名指令 197
10.4 程序集的结构 198
10.5 程序集标识符 199
10.6 强命名程序集 200
10.7 程序集的私有方式部署 201
10.8 共享程序集和GAC 201
10.8.1 把程序集安装到GAC 201
10.8.2 GAC 内的并肩执行 202
10.9 配置文件 203
10.10 延迟签名 203
第11 章 异常 205
11.1 什么是异常 205
11.2 try 语句 206
11.3 异常类 207
11.4 catch 子句 207
11.4.1 使用特定catch 子句的示例 208
11.4.2 catch 子句段 209
11.5 finally 块 210
11.6 为异常寻找处理代码 211
11.7 更进一步搜索 211
11.7.1 一般法则 212
11.7.2 搜索调用栈的示例 213
11.8 抛出异常 214
11.9 不带异常对象的抛出 215
第12 章 结构 217
12.1 什么是结构 217
12.2 结构是值类型 218
12.3 对结构赋值 219
12.4 构造函数和析构函数 220
12.4.1 实例构造函数 220
12.4.2 静态构造函数 221
12.4.3 构造函数和析构函数的总结 221
12.5 ?段初始化是不允许的 222
12.6 结构是密封的 222
12.7 装箱和取消装箱 222
12.8 结构作为返回值和参数 222
12.9 关于结构的附加信息 222
第13 章 枚举 224
13.1 枚举 224
13.11 设置底层类型和显式值 225
13.12 隐式成员编号 226
13.2 位标志 227
13.21 Flags 特性 229
13.22 使用位标志的示例 230
13.3 关于枚举的补充 231
第14 章 数组 233
14.1 数组 233
14.1.1 定义 233
14.1.2 重要细节 234
14.2 数组的类型 234
14.3 数组是对象 235
14.4 一维数组和矩形数组 236
14.5 实例化一维数组或矩形数组 236
14.6 访问数组元素 237
14.7 初始化数组 238
14.7.1 显式初始化一维数组 238
14.7.2 显式初始化矩形数组 239
14.7.3 初始化矩形数组的语法点 ?239
14.7.4 快捷语法 240
14.7.5 隐式类型数组 240
14.7.6 综合内容 241
14.8 交错数组 241
14.8.1 声明交错数组 242
14.8.2 快捷实例化 242
14.8.3 实例化交错数组 242
14.8.4 交错数组中的子数组 243
14.9 比较矩形数组和交错数组 244
14.10 foreach 语句 245
14.10.1 迭代变量是只读的 246
14.10.2 foreach 语句和多维数组 247
14.11 数组协变 248
14.12 数组继承的有用成员 249
14.13 比较数组类型 252
第15 章 委托 253
15.1 什么是委托 253
15.2 声明委托类型 255
15.3 创建委托对象 255
15.4 赋值委托 257
15.5 组合委托 257
15.6 为委托增加方法 258
15.7 从委托移除方法 259
15.8 调用委托 259
15.9 委托的示例 260
15.10 调用带返回值的委托 261
15.11 调用带引用参数的委托 262
15.12 匿名方法 262
15.12.1 使用匿名方法 263
15.12.2 匿名方法的语法 263
15.12.3 变量和参数的作用域 265
15.13 Lambda 表达式 266
第16 章 事件 269
16.1 事件和委托相似 269
16.2 源代码组件概览 270
16.3 声明事件 271
16.3.1 事件是成员 271
16.3.2 委托类型和EventHandler 272
16.4 触发事件 272
16.5 订阅事件 273
16.6 标准事件的用法 275
16.6.1 使用EventArgs 类 275
16.6.2 通过扩展EventArgs 来传递数据 276
16.6.3 使用自定义委托 276
16.7 MyTimerClass 代码 278
16.8 事件访问器 279
第17 章 接口 280
17.1 什么是接口 280
17.2 声明接口 283
17.3 实现接口 284
17.4 接口是引用类型 285
17.5 接口和as 运算符 287
17.6 实现多个接口 287
17.7 实现具有重复成员的接口 288
17.8 多个接口的引用 289
17.9 派生成员作为实现 291
17.10 显式接口成员实现 291
17.11 接口可以继承接口 294
第18 章 转换 297
18.1 什么是转换 297
18.2 隐式转换 298
18.3 显式转换和强制转换 299
18.4 转换的类? 300
18.5 数字的转换 301
18.5.1 隐式数字转换 301
18.5.2 溢出检测上下文 302
18.5.3 显式数字转换 303
18.6 引用转换 306
18.6.1 隐式引用转换 307
18.6.2 显式引用转换 308
18.6.3 有效显式引用转换 308
18.7 装箱转换 309
18.8 拆箱转换 311
18.9 用户自定义转换 312
18.9.1 用户自定义转换的约束 312
18.9.2 用户自定义转换的示例 313
18.9.3 计算用户自定义转换 314
18.9.4 多步用户自定义转换的示例 315
18.10 is 运算符 316
18.11 as 运算符 317
第19 章 泛型 318
19.1 什么是泛型 318
19.2 C#中的泛型 320
19.3 泛型类 321
19.4 声明泛型类 321
19.5 创建构造类型 322
19.6 创建变量和实例 323
19.6.1 使用泛型的栈的示例 324
19.6.2 比较泛型和非泛型栈 325
19.7 类型参数的约束 326
19.7.1 Where 子句 327
19.7.2 约束类型和次序 327
19.8 泛型方法 328
19.8.1 声明泛型方法 328
19.8.2 调用泛型方法 329
19.8.3 泛型方法的示例 330
19.9 扩展方法和泛型类 331
19.10 泛型结构 332
19.11 泛型委托 332
19.12 泛型接口 334
19.12.1 使用泛型接口的示例 335
19.12.2 泛型接口的实现必须** 336
19.13 泛型的协变和逆变 337
19.13.1 接口的协变和逆变 341
19.13.2 有关变化的更多内容 342
第20 章 枚举数和迭代器 344
20.1 枚举数和可枚举类型 344
20.1.1 使用foreach 语句 344
20.1.2 枚举数类型 345
20.2 使用IEnumerator 接口 346
20.3 IEnumerable 接口 349
20.4 不实现接口的枚举数 351
20.5 泛型枚举接口 352
20.6 IEnumerator接口 352
20.7 IEnumerable接口 354
20.8 迭代器 355
20.8.1 迭代器块 356
20.8.2 使用迭代器来创建枚举数 357
20.8.3 使用迭代器来创建可枚举类型 358
20.9 常见迭代器模式 360
20.10 产生可枚举类型和枚举数 360
20.11 产生多个可枚举类型 361
20.12 产生多个枚举数 362
20.13 迭代器实质 363
第21 章 介绍LINQ 365
21.1 什么是LINQ 365
21.2 LINQ 提供程序 366
21.3 查询语法和方法语法 368
21.4 查询变量 369
21.5 查询表达式的结构 370
21.5.1 from 子句 371
21.5.2 join 子句 372
21.5.3 什么是联结 373
21.5.4 查询主体中的fromletwhere 片段 375
21.5.5 orderby 子句 378
21.5.6 select…group 子句 378
21.5.7 查询中的匿名类型 380
21.58 group 子句 380
21.5.9 查询延续 382
21.6 标准查询运算符 383
21.6.1 查询表达式和标准查询运算符 384
21.6.2 标准查询运算符的签名 385
21.6.3 委托作为参数 386
21.6.4 LINQ 预定义的委托类型 387
21.6.5 使用委托参数的示例 388
21.6.6 使用Lambda 表达式参数的示例 388
21.7 LINQ to XML 390
21.7.1 标记语言 390
21.7.2 XML 基础 390
21.7.3 XML 类 391
21.7.4 使用XML 树的值 394
21.7.5 使用XML 属性 397
21.7.6 节点的其他类型 400
21.7.7 使用LINQ to XML 的LINQ 查询 401
第22 章 异步编程简介 404
22.1 进程、线程以及异步编程 404
22.1.1 多线程处理带来的问题 405
22.1.2 多线程处理的复杂度 405
22.2 并行循环 406
22.3 BackgroundWorker 类 408
22.3.1 BackgroundWorker 类的示例代码 411
22.3.2 BackgroundWorker 用于WPF 程序的例子 414
22.4 异步编程模式 416
22.5 BeginInvoke 和EndInvoke 417
22.5.1 等待—直到结束模式 418
22.5.2 AsyncResult 类 419
22.5.3 轮询模式 420
22.5.4 回调模式 421
22.6 计时器 423
第23 章 预处理指令 426
23.1 什么是预处理指令 426
23.2 基本规则 426
23.3 #define 和#undef 指令 427
23.4 条件编译 428
23.5 条件编译结构 429
23.6 诊断指令 431
23.7 行号指令 431
23.8 区域指令 432
23.9 #pragma warning 指令 433
第24 章 反射和特性 434
24.1 元数据和反射 434
24.2 Type 类 435
24.3 获取Type 对象 436
24.4 什么是特性 438
24.5 应用特性 439
24.6 预定义的保留的特性 439
24.6.1 Obsolete 特性 439
24.6.2 Conditional 特性 440
24.6.3 预定义的特性 441
24.7 有关应用特性的更多内容 442
24.7.1 多个特性 442
24.7.2 其他类型的目标 442
24.7.3 全局特性 443
24.8 自定义特性 443
24.8.1 声明自定义特性 444
24.8.2 使用特性的构造函数 444
24.8.3 指定构造函数 444
24.8.4 使用构造函数 445
24.8.5 构造函数中的位置参数和命名参数 445
24.8.6 限制特性的使用 446
24.8.7 自定义特性的*佳实践 447
24.9 访问特性 448
24.9.1 使用IsDefined 方法 448
24.9.2 使用GetCustomAttribute方法 449
第25 章 其他主题 450
25.1 概述 450
25.2 字符串 450
25.2.1 使用StringBuilder 类 451
25.2.2 格式化数字字符串 452
25.3 把字符串解析为数据值 455
25.4 关于可空类型的更多内容 457
25.4.1 使用空接合运算符 458
25.4.2 使用可空用户自定义类型 459
25.5 Main 方法 460
25.6 文档注释 461
25.6.1 插入文档注释 462
25.6.2 使用其他XML 标签 463
25.7 嵌套类型 463
25.7.1 嵌套类的示例 464
25.7.2 可见性和嵌套类型 465
25.8 和COM 的互操作 467
《C# 4.0图解教程》文章节选:
译 者 序
C#是一门基于.NET的**语言,正是因为C#处于.NET温暖的怀抱,所以许多C#程序员,甚至许多C#**程序员对.NET在内存和指令等本质问题上的认识不够。况且有许多使用C#的程序员在使用ASP.NET技术进行网站开发,他们有的从脚本语言转型而来,有的在没有充分学习C#的情况下就投入了开发工作,那么他们可能对本质问题的?识就更差一点。但是笔者认为,不管怎么样,都非常有必要更深入理解语言背后的机制,而不仅仅停留在掌握API使用的层次上。只有这样,你才能意识到很多bug的关键点和性能问题的关键点,并且理解那些**的特性。
从目录上来看本书就像其他C#入门书籍一样,介绍了一个又一个语言特性,但是如果你翻阅一下正文就会发现它的不同。可能因为作者有C/C++的背景的关系,对于每一个语言特性,作者对其使用方式只是轻描淡写,而对特性背后的机制做了浓墨重彩的介绍,并且在文字介绍中穿插大量图示来展现内存对象的面貌。其实,市面上很多所谓的进阶书籍都只是介绍如何使用那些**API、**特性,而忽略了语言本质,但这一块恰巧是*重要的。因此,对于那些用了几年C#的程序员来说,本书具有非常大的价值。
不管怎样,一句话,本书值得一读。但是由于时间仓促,本书在翻译过程中难免出现失误,如果有任何问题,欢迎来信交流,笔者邮箱为yzhu@live.com。 朱 晔
2011年3月 前 言
本书的目的是讲授C#编程语言的基础知识和工作原理。大多数编程图书以文字为主要载体。对于小说而言,文字形式当然是*恰当不过了,但对于编程语言中的很多重要概念,综合运用文字、图形和表格会更容易理解。
许多人都习惯于形象思维,而图形和表格有助于我们更清晰地理解概念。在几年的编程语言教学工作中我发现,我在白板上画的图能帮助学生*快地理解我要传达的概念。然而,单靠图表并不足以解释一种编程语言和平台。本书的目标是以*佳方式结合文字和图表,使你对这种语言有透彻的理解,并且让本书能用作参考工具。
本书写给所有想要学习C#的人——从初学者到有经验的程序员。刚开始学编程的人会发现,书中全面讲述了基础知识;有经验的程序员会觉得,内容的叙述非常简洁明晰,无需费力卒读就能直接获得想要的信息。无论哪种程序员,内容本身的图形化呈现方式都能帮助你更容易地学习本书。
你可以从Apress网站(apress.com)下载本书所有示例程序的源代码 。尽管我不能回答有关代码的一些细节问题,但是你可以通过dansolis@sbcglobal.net和我取得联系,提出建议或反馈,还可以访问我的站点illustratedcsharp.com。*后?如果你有兴趣对学习使用Windows Presentation Foundation来编程,可以阅读我的另外一本书——Illustrated WPF,该书的风格及叙述方式和本书一样。
我希望本书可以让你享受学习C#的过程!祝你好运!
致谢
我想感谢Sian每天支持并鼓励我,我还想感谢我的父母、兄弟和姐妹,他们一直爱我并支持我。
我还想对Apress的朋友表达诚挚的感谢,是他们与我携手完成了本书。我真心感激他们理解并赏识我努力做的事情,并和我一起完成它。感谢你们所有人。 第1章 C#和.NET框架 本章内容
在.NET之前
进入Microsoft .NET
编译成CIL 编译成本机代码并执行 CLR
CLI
缩写回顾
1.1 在.NET之前
C#编程语言是为在微软公司的.NET框架 上开发程序而设计的。本章将简要介绍.NET从何而来,以及它的基本架构。在开始之前,我要指出其正确发音:see sharp 。
1.1.1 20世纪90年代后期的Windows编程
在20世纪90年代后期,使用微软平台的Windows编程分化成许多分支。大多数程序员在使用Visual Basic(VB)、C或C++。一些C和C++程序员在使用纯Win32 API,但大多数人在使用MFC(Microsoft Foundation Classes,微软基础类库)。其他人已经转向了COM(Component Object Model,组件对象模型)。
所有这些技术都有自己的问题。纯Win32 API不是面向对象的,而且使用它的工作量比使用MFC的更大。MFC是面向对象的,但是它却不一致,并逐渐变得陈旧。COM虽然概念简单,但它的实际代码复杂,并且需要很多丑陋的、不雅的底层基础代码。
所有这些编程技术的另外一个缺点是它们主要针对桌面程序而不是Internet进行开发。那时,Web编程还是以后的事情,而且看起来和桌面编程非常不同。
1.1.2 下一代平台服务的目标
我们真正需要的是一个新的开始——一个集成的、面向对象的开发框架,它可以把一致和优雅带回编程。为满足这个需求,微软宣布开发一个代码执行环境和一个可以实现这些目标的代码开发环境。这些目标列在图1-1中。
1.2 进入Microsoft .NET
在2002年,微软发布了.NET框架的**个版本,声称其解决了旧问题并实现了下一代系统的目标。.NET框架是一种比MFC和COM编程技术更一致并面向对象的环境。它的特点包括以下几点。
? 多平台 该系统可以在多种多样的计算机上运行,从服务器、桌面机到PDA和移动电话。
? 行业标准 该系统使用行业标准的通信协议,比如XML、HTTP、SOAP和WSDL。
? **性 该系统能提供更加**的执行环境,即使有来源可疑的代码存在。
1.2.1 .NET框架的组成
.NET框架由三部分组成,如图1-2所示。 执行环境称为CLR(Common Language Runtime,公共语言运行库)。CLR在运行期管理程序的执行,包括以下内容。
内存管理。
代码**验证。
代码执行、线程管理及异常处理。
垃圾收集。
编程工具涵盖了编码和调试需要的一?,包括以下几点。
Visual Studio集成开发环境。
.NET兼容的编译器(例如:C#、VB、.NET、JScript、F#、IronRuby和托管的C++)。
调试器。
网站开发服务器端技术,比如ASP.NET或WCF。
BCL(Base Class Library,基类库)是.NET框架使用的一个大的类库,而且也可以在你的程序中使用。
1.2.2 大大改进的编程环境
较之以前的Windows编程环境,.NET框架为程序员带来了相当大的改进。下面几节将简要阐述它的特点及其带来的好处。
1.面向对象的开发环境
CLR、BCL和C#被设计得?全面向对象,并形成良好的集成环境。
系统为本地程序和分布式系统都提供了一致的、面向对象的编程模型。它还为桌面应用程序、移动应用程序和Web开发提供了软件开发接口,涉及的目标范围很广,从计算机服务器到手机。
2.自动垃圾收集
CLR有一项服务称为GC(Garbage Collector,垃圾收集),它能为你自动管理内存。
? GC自动从内存中删除程序不再访问的对象。
? GC使程序员不再操心许多以前必须执行的任务,比如释放内存和检查内存泄漏。这可是个很大的改进,因为检查内存泄漏可能非常困难而且耗时?
3.互操作性
.NET框架专门考虑了不同的.NET语言、操作系统或Win32 DLL和COM之间的互操作性。
? .NET语言的互操作性允许用不同的.NET语言编写的软件模块无缝地交互。
? 一种.NET语言写的程序可以使用甚至继承用另外一种.NET语言写的类,只需要遵循一定的规则即可。
? 正因为能够很容易地集成不同编程语言生成的模块,.NET框架有时被称为是语言无关的。
? .NET提供一种称为平台调用(platform invoke, P/Invoke)的特性,允许.NET的代码调用并使用非.NET的代码。它可以使用标准Win32 DLL导出的纯C函数的代码,比如Windows API。
? .NET框架还允许与COM进行互操作。.NET框架软件组件能调用COM组件,而且COM组件也能调用.NET组件,就像它们是COM组件一样。
4.不需要COM
.NET框架使程序员摆脱了COM的束缚。作为一个C#程序员,不需要使用COM,因而也不需要下面这些内容。
? IUnknown接口 在COM中,所有对象必须实现IUnknown接口。相反,所有.NET对象都继承一个名为object的类。接口编程仍是.NET中的一个重要部分,但不再是**主题了。
? 类型库 在COM中,类型信息作为.tlb?件保存在类型库中,它和可执行代码是分开的。在.NET中,程序的类型信息和代码一起被保存在程序文件中。
? 引用计数 在COM中,程序员必须记录一个对象的引用数目以确保它不会在错误的时间被删除。在.NET中,GC记录引用情况并只在合适的时候删除对象。
HRESULT COM使用HRESULT数据类型返回运行时错误代码。.NET不使用HRESULT。相反,所有意外的运行时错误都产生异常。
注册表 COM应用必须在系统注册表中注册。注册表保存了与操作系统的配置和应用程序有关的信息。.NET应用不需要使用注册表,这简化了程序的安装和卸载。(但是有类似的东西,称为全局程序集缓存,即GAC,我会在第10章阐述。)
尽管现在不太需要编写COM代码了,但是系统中还是在使用很多COM组件,C#程序员有的时候需要编写代码来和那些组件交互。C# 4.0引入了几个新的特性,来简化这个工作。
5.简化的部署
部署为.NET框架编写的程序比以前容易很多,原因如下。
.NET程序不需要使用注册表注册,这意味着在*简单的情形下,一个程序只需要被复制到目标机器上便可以运行。
.NET提供一种称为并行执行的特性,允许一个DLL的不同版本在同一台?器上存在。这意味着每个可执行程序都可以访问程序生成时使用的那个版本的DLL。
6.类型**性
CLR检查并确保参数及其他数据对象的类型**,即使是在不同编程语言编写的组件之间。
7.基类库
.NET框架提供了一个庞大的基础类库,很自然地,它被称为基类库(Base Class Library, BCL)。(有时称为框架类库——Framework Class Library,FCL。) 在写自己的程序时,可以使用这些丰富的代码。包括以下一些类。
? 通用基础类 这些类提供了一组极为强大的工具,可以应用到许多编程任务中,比如文件操作、字符串操作、**和加密。
? 集合类 这些类实现了列表、字典、散列表以及位数组。
? 线程和同步类 这些类用于创建多线程程序。
? XML类 这些类用于创建、读取以及操作XML文档。
1.3 编译成CIL
.NET语言的编译器接受源代码文件,并生成名为程序集的输出文件。图1-3阐述了这个过程。
? 程序集要么是可执行的,要么是DLL。
? 程序集里的代码并不是本机代码,而是一种名称为CIL(Common Intermediate Language,公共中间语言)的中间语言。
? 程序集包含的信息?,包括下列项目:
? 程序的CIL;
? 程序中使用的类型的元数据;
? 对其他程序集引用的元数据。
随着时间的推移,公共中间语言的缩写已经改变,而且不同的参考书可能使用不同的术语。可能会遇到的其他两个CIL的术语是IL(Intermediate Language)和MSIL(Microsoft Intermediate Language),它们在.NET发展初期和早期文档中频繁使用。
1.4 编译成本机代码并执行
程序的CIL直到它被调用运行时才会被编译成本机代码。在运行时,CLR执行下面的步骤(如图1-4所示):
(1) 检查程序集?**特性;
(2) 在内存中分配空间;
(3) 把程序集中的可执行代码发送给实时(Just-in- Time, JIT)编译器,把其中的一部分编译成本机代码。
程序集中的可执行代码只在需要的时候由JIT编译器编译,然后它就被缓存起来以备在后来的程序中执行。使用这个方法意味着不被调用的代码不会被编译成本机代码,而且被调用到的代码只被编译一次。
一旦CIL被编译成本机代码,CLR就在它运行时管理它,执行像释放无主内存、检查数组边界、检查参数类型和管理异常之类的任务。有两个重要的术语由此而生。
? 托管代码 为.NET框架编写的代码称为托管代码(managed code),需要CLR。
? 非托管代码 不在CLR控制之下运行的代码,比如Win32 C/C++ DLL,称为非托管代码(unmanaged code)。
微软公司还提供了一个称为本机映像生成器或Ngen的工具,可以把一个程序集转换成当前处理器的本机代码。经过Ngen处理过的代码免除了运行时的JIT编译过程。
编译和执行
无论原始源文件的语言是什么,都遵循同样的编译和执行过程。图1-5说明了3个用不同语言编写的程序的完整编译和运行期过程。
1.5 CLR
.NET框架的核心组件是CLR,?在操作系统的顶层,负责管理程序的执行,如图1-6所示。
CLR还提供下列服务: 自动垃圾收集; **和认证;
通过访问BCL得到广泛的编程功能,包括如Web服务和数据服务之类的功能。
1.6 CLI
每种编程语言都有一组内置的类型,用来表示如整数、浮点数和字符等之类的对象。在历史上,这些类型的特征因编程语言和平台的不同而不同。例如,组成整数的位数对于不同的语言和平台就有很大差别。
然而,这种统一性的缺乏使我们难以让使用不同语言编写的程序及库一起良好协作。为了有序协作,必须有一组标准。
CLI(Common Language Infrastructure,公共语言基础结构)就是这样一组标准,它把所有.NET框架的组件连结成一个内聚的、一致的系统。它展示了系统的概念和架构,并详细说明了所有软件都必须坚持的规则和约定。CLI的组成如图1-7所示。
CLI和C#都已经被Ecma International批准为开放的国际标准规范。[“Ecma”本来是Europen Computer Manufacturers Association(欧洲计算机制造商协会)的缩写,但现在就是一个词。]Ecma的成员包括微软、IBM、惠普、Adobe等众多和计算机及消费性电子产品有关的公司。
CLI的重要组成部分
虽然大多数程序员不需要了解CLI规范的细节,但至少应该熟悉公共类型系统和公共语言规范的含义和目的。
1. 公共类型系统
CTS(Common Type System,公共类型系统)定义了那些在托管代码中一定会使用的类型的特征。CTS的一些重要方面如下。
? CTS定义了一组丰富的内置类型,以及每种类型固有的、独有的特性。
? .NET兼容编程语言提供的类型通常映射到CTS中已定义的内置类型集的某一个特殊子集。
? CTS*重要的特征之一是所有类型都继承自公共的基类——object。
2. 公共语言规范
CLS(Common Language Specification,公共语言规范)详细说明了一个.NET兼容编程语言的规则、属性和行为,其主题包括数据类型、类结构和参数传递。
1.7 缩写回顾
本章包含了许多.NET缩写,所以*后再加入图1-8帮助你直观地理解它们。
《C# 4.0图解教程》作者介绍:
Daniel M. Solis **软件工程师和技术顾问,有20余年开发经验,曾为微软和IBM等大公司提供技术咨询。他拥有加州大学计算机科学硕士、生物学和英文学士学位。同时,他也是一位杰出的导师,在美国和欧洲从事编程语言、Windows程序设计和Unix底层技术相关的教学培训工作多年。