目录
1.
简介
......................................................................................................................................................
1
1.1 Hello world
.........................................................................................................................................
1
1.2
程序结构
..........................................................................................................................................
2
1.3
类型和变量
.......................................................................................................................................
4
1.4
表达式
..............................................................................................................................................
6
1.5
语句
..................................................................................................................................................
8
1.6
类和对象
.........................................................................................................................................
11
1.6.1
成员
12
1.6.2
可访问性
.................................................................................................................................. 12
1.6.3
基类
13
1.6.4
字段
13
1.6.5
方法
14
1.6.5.1
参数
....................................................................................................................................
14
1.6.5.2
方法体和局部变量
.............................................................................................................
15
1.6.5.3
静态方法和实例方法
..........................................................................................................
16
1.6.5.4
虚方法、重写方法和抽象方法
...........................................................................................
17
1.6.5.5
方法重载
............................................................................................................................
19
1.6.6
其他函数成员
........................................................................................................................... 20
1.6.6.1
构造函数
............................................................................................................................
21
1.6.6.2
属
21
性
...............................................................................................................................
21
1.6.6.3
索引器
................................................................................................................................
22
1.6.6.4
事件
....................................................................................................................................
22
1.6.6.5
运算符
................................................................................................................................
23
1.6.6.6
析构函数
............................................................................................................................
23
1.7
结构
................................................................................................................................................
24
1.8
数组
................................................................................................................................................
25
1.9
接口
................................................................................................................................................
26
1.10
枚举
..............................................................................................................................................
27
1.11
委托
..............................................................................................................................................
28
1.12
属性
..............................................................................................................................................
29
2.
词法结构
............................................................................................................................................
31
2.1
程序
................................................................................................................................................
31
2.2
文法
................................................................................................................................................
31
2.2.1
文法表示法
............................................................................................................................... 31
2.2.2
词法文法
.................................................................................................................................. 32
2.2.3
句法文法
.................................................................................................................................. 32
2.3
词法分析
.........................................................................................................................................
32
2.3.1
行结束符
.................................................................................................................................. 33
2.3.2
注释
33
2.3.3
空白
35
2.4
标记
................................................................................................................................................
35
2.4.1 Unicode 字符转义序列.............................................................................................................. 35
2.4.2
标识符
...................................................................................................................................... 36
2.4.3
关键字
...................................................................................................................................... 38
2.4.4
文本
38
2.4.4.1
布尔值
................................................................................................................................
38
2.4.4.2
整数
....................................................................................................................................
38
2.4.4.3
实数
....................................................................................................................................
40
2.4.4.4
字符
....................................................................................................................................
40
2.4.4.5
字符串
................................................................................................................................
41
2.4.4.6
空文本
................................................................................................................................
43
2.4.5
运算符和标点符号
................................................................................................................... 43
2.5
预处理指令
.....................................................................................................................................
43
2.5.1
条件编译符号
........................................................................................................................... 44
2.5.2
预处理表达式
........................................................................................................................... 45
2.5.3
声明指令
.................................................................................................................................. 45
2.5.4
条件编译指令
........................................................................................................................... 46
2.5.5
诊断指令
.................................................................................................................................. 49
2.5.6
区域指令
.................................................................................................................................. 49
2.5.7
行指令
...................................................................................................................................... 50
3.
基本概念
............................................................................................................................................
51
3.1
应用程序启动
.................................................................................................................................
51
3.2
应用程序终止
.................................................................................................................................
52
3.3
声明
................................................................................................................................................
52
3.4
成员
................................................................................................................................................
54
3.4.1
命名空间成员
........................................................................................................................... 54
3.4.2
结构成员
.................................................................................................................................. 54
3.4.3
枚举成员
.................................................................................................................................. 55
3.4.4
类成员
...................................................................................................................................... 55
3.4.5
接口成员
.................................................................................................................................. 55
3.4.6
数组成员
.................................................................................................................................. 55
3.4.7
委托成员
.................................................................................................................................. 55
3.5
成员访问
.........................................................................................................................................
56
3.5.1
已声明可访问性
....................................................................................................................... 56
3.5.2
可访问域
.................................................................................................................................. 57
3.5.3
实例成员的受保护访问
............................................................................................................ 59
3.5.4
可访问性约束
........................................................................................................................... 59
3.6
签名和重载
.....................................................................................................................................
60
3.7
范围
................................................................................................................................................
61
3.7.1
名称隐藏
.................................................................................................................................. 63
3.7.1.1
通过嵌套隐藏
.....................................................................................................................
63
3.7.1.2
通过继承隐藏
.....................................................................................................................
64
3.8
命名空间和类型名称
......................................................................................................................
65
3.8.1
完全限定名
............................................................................................................................... 66
3.9
自动内存管理
.................................................................................................................................
67
3.10
执行顺序
.......................................................................................................................................
69
4.
类型
....................................................................................................................................................
71
4.1
值类型
............................................................................................................................................
71
4.1.1 System.ValueType
类型
............................................................................................................. 72
4.1.2
默认构造函数
........................................................................................................................... 72
4.1.3
结构类型
.................................................................................................................................. 73
4.1.4
简单类型
.................................................................................................................................. 73
4.1.5
整型
74
4.1.6
浮点型
...................................................................................................................................... 75
4.1.7 decimal
类型
.............................................................................................................................. 76
4.1.8 bool
类型
................................................................................................................................... 76
4.1.9
枚举类型
.................................................................................................................................. 77
4.2
引用类型
.........................................................................................................................................
77
4.2.1
类类型
...................................................................................................................................... 77
4.2.2
对象类型
.................................................................................................................................. 78
4.2.3 string
类型
................................................................................................................................. 78
4.2.4
接口类型
.................................................................................................................................. 78
4.2.5
数组类型
.................................................................................................................................. 78
4.2.6
委托类型
.................................................................................................................................. 78
4.3
装箱和拆箱
.....................................................................................................................................
79
4.3.1
装箱转换
.................................................................................................................................. 79
4.3.2
拆箱转换
.................................................................................................................................. 80
5.
变量
....................................................................................................................................................
81
5.1
变量类别
.........................................................................................................................................
81
5.1.1
静态变量
.................................................................................................................................. 81
5.1.2
实例变量
.................................................................................................................................. 81
5.1.2.1
类中的实例变量
.................................................................................................................
81
5.1.2.2
结构中的实例变量
.............................................................................................................
82
5.1.3
数组元素
.................................................................................................................................. 82
5.1.4
值参数
...................................................................................................................................... 82
5.1.5
引用参数
.................................................................................................................................. 82
5.1.6
输出参数
.................................................................................................................................. 82
5.1.7
局部变量
.................................................................................................................................. 83
5.2
默认值
............................................................................................................................................
83
5.3
明确赋值
.........................................................................................................................................
84
5.3.1
初始已赋值变量
....................................................................................................................... 84
5.3.2
初始未赋值变量
....................................................................................................................... 85
5.3.3
确定明确赋值的细则
................................................................................................................ 85
5.3.3.1
一般语句规则
.....................................................................................................................
85
5.3.3.2
块语句、
checked
和
unchecked
语句
................................................................................
86
5.3.3.3
表达式语句
.........................................................................................................................
86
5.3.3.4
声明语句
............................................................................................................................
86
5.3.3.5 if
语句
.................................................................................................................................
86
5.3.3.6 switch
语句
.........................................................................................................................
87
5.3.3.7 while
语句
...........................................................................................................................
87
5.3.3.8 do
语句
...............................................................................................................................
87
5.3.3.9 for
语句
...............................................................................................................................
87
5.3.3.10 break
、
continue
和
goto
语句
...........................................................................................
88
5.3.3.11 throw
语句
.........................................................................................................................
88
5.3.3.12 return
语句
........................................................................................................................
88
5.3.3.13 try-catch
语句
....................................................................................................................
88
5.3.3.14 try-finally
语句
...................................................................................................................
88
5.3.3.15 try-catch-finally
语句
..........................................................................................................
89
5.3.3.16 foreach
语句
......................................................................................................................
90
5.3.3.17 using
语句
..........................................................................................................................
90
5.3.3.18 lock
语句
...........................................................................................................................
90
5.3.3.19
简单表达式的一般规则
....................................................................................................
90
5.3.3.20
带有嵌入表达式的表达式的一般规则
..............................................................................
91
5.3.3.21
调用表达式和对象创建表达式
.........................................................................................
91
5.3.3.22
简单赋值表达式
...............................................................................................................
91
5.3.3.23 &&
表达式
.......................................................................................................................
92
5.3.3.24 ||
表达式
............................................................................................................................
92
5.3.3.25 !
表达式
............................................................................................................................
93
5.3.3.26 ?:
表达式
...........................................................................................................................
93
5.4
变量引用
.........................................................................................................................................
94
5.5
变量引用的原子性
..........................................................................................................................
94
6.
转换
....................................................................................................................................................
95
6.1
隐式转换
.........................................................................................................................................
95
6.1.1
标识转换
.................................................................................................................................. 95
6.1.2
隐式数值转换
........................................................................................................................... 95
6.1.3
隐式枚举转换
........................................................................................................................... 96
6.1.4
隐式引用转换
........................................................................................................................... 96
6.1.5
装箱转换
.................................................................................................................................. 97
6.1.6
隐式常量表达式转换
................................................................................................................ 97
6.1.7
用户定义的隐式转换
................................................................................................................ 97
6.2
显式转换
.........................................................................................................................................
97
6.2.1
显式数值转换
........................................................................................................................... 97
6.2.2
显式枚举转换
........................................................................................................................... 99
6.2.3
显式引用转换
........................................................................................................................... 99
6.2.4
拆箱转换
................................................................................................................................. 100
6.2.5
用户定义的显式转换
.............................................................................................................. 100
6.3
标准转换
.......................................................................................................................................
100
6.3.1
标准隐式转换
......................................................................................................................... 100
6.3.2
标准显式转换
......................................................................................................................... 101
6.4
用户定义的转换
............................................................................................................................
101
6.4.1
允许的用户定义转换
.............................................................................................................. 101
6.4.2
用户定义的转换的计算
.......................................................................................................... 101
6.4.3
用户定义的隐式转换
.............................................................................................................. 102
6.4.4
用户定义的显式转换
.............................................................................................................. 102
7.
表达式
..............................................................................................................................................
105
7.1
表达式的分类
...............................................................................................................................
105
7.1.1
表达式的值
............................................................................................................................. 106
7.2
运算符
...........................................................................................................................................
106
7.2.1
运算符的优先级和顺序关联性
............................................................................................... 106
7.2.2
运算符重载
............................................................................................................................. 107
7.2.3
一元运算符重载决策
.............................................................................................................. 108
7.2.4
二元运算符重载决策
.............................................................................................................. 109
7.2.5
候选用户定义运算符
.............................................................................................................. 109
7.2.6
数值提升
................................................................................................................................. 109
7.2.6.1
一元数值提升
...................................................................................................................
110
7.2.6.2
二元数值提升
...................................................................................................................
110
7.3
成员查找
.......................................................................................................................................
111
7.3.1
基类型
.................................................................................................................................... 111
7.4
函数成员
.......................................................................................................................................
112
7.4.1
参数列表
................................................................................................................................. 114
7.4.2
重载决策
................................................................................................................................. 116
7.4.2.1
适用函数成员
...................................................................................................................
116
7.4.2.2
更好的函数成员
...............................................................................................................
117
7.4.2.3
更好的转换
.......................................................................................................................
117
7.4.3
函数成员调用
......................................................................................................................... 118
7.4.3.1
已装箱实例上的调用
........................................................................................................
119
7.5
基本表达式
...................................................................................................................................
119
7.5.1
文本
120
7.5.2
简单名称
................................................................................................................................. 120
7.5.2.1
块中的固定含义
...............................................................................................................
121
7.5.3
带括号的表达式
..................................................................................................................... 122
7.5.4
成员访问
................................................................................................................................. 122
7.5.4.1
相同的简称和类型名称
....................................................................................................
123
7.5.5
调用表达式
............................................................................................................................. 124
7.5.5.1
方法调用
...........................................................................................................................
124
7.5.5.2
委托调用
...........................................................................................................................
125
7.5.6
元素访问
................................................................................................................................. 125
7.5.6.1
数组访问
...........................................................................................................................
126
7.5.6.2
索引器访问
.......................................................................................................................
126
7.5.7 this
访问
.................................................................................................................................. 127
7.5.8 base
访问
................................................................................................................................ 127
7.5.9
后缀增量和后缀减量运算符
................................................................................................... 128
7.5.10 new
运算符
........................................................................................................................... 129
7.5.10.1
对象创建表达式
..............................................................................................................
129
7.5.10.2
数组创建表达式
..............................................................................................................
130
7.5.10.3
委托创建表达式
..............................................................................................................
131
7.5.11 typeof
运算符
........................................................................................................................
133
7.5.12 checked
和
unchecked
运算符
..............................................................................................
133
7.6
一元运算符
...................................................................................................................................
136
7.6.1
一元加运算符
.........................................................................................................................
136
7.6.2
一元减运算符
.........................................................................................................................
136
7.6.3
逻辑否定运算符
.....................................................................................................................
137
7.6.4
按位求补运算符
.....................................................................................................................
137
7.6.5
前缀增量和减量运算符
.......................................................................................................... 137
7.6.6
强制转换表达式
..................................................................................................................... 138
7.7
算术运算符
...................................................................................................................................
139
7.7.1
乘法运算符
............................................................................................................................. 139
7.7.2
除法运算符
............................................................................................................................. 140
7.7.3
余数运算符
............................................................................................................................. 141
7.7.4
加法运算符
............................................................................................................................. 142
7.7.5
减法运算符
............................................................................................................................. 144
7.8
移位运算符
...................................................................................................................................
146
7.9
关系和类型测试运算符
................................................................................................................
147
7.9.1
整数比较运算符
..................................................................................................................... 147
7.9.2
浮点比较运算符
..................................................................................................................... 148
7.9.3
小数比较运算符
..................................................................................................................... 149
7.9.4
布尔相等运算符
..................................................................................................................... 149
7.9.5
枚举比较运算符
..................................................................................................................... 149
7.9.6
引用类型相等运算符
.............................................................................................................. 149
7.9.7
字符串相等运算符
.................................................................................................................. 151
7.9.8
委托相等运算符
..................................................................................................................... 151
7.9.9 is
运算符
................................................................................................................................. 151
7.9.10 as
运算符
.............................................................................................................................. 152
7.10
逻辑运算符
.................................................................................................................................
152
7.10.1
整数逻辑运算符
.................................................................................................................... 153
7.10.2
枚举逻辑运算符
.................................................................................................................... 153
7.10.3
布尔逻辑运算符
.................................................................................................................... 153
7.11
条件逻辑运算符
..........................................................................................................................
153
7.11.1
布尔条件逻辑运算符
............................................................................................................ 154
7.11.2
用户定义的条件逻辑运算符
................................................................................................. 154
7.12
条件运算符
.................................................................................................................................
155
7.13
赋值运算符
.................................................................................................................................
156
7.13.1
简单赋值
............................................................................................................................... 156
7.13.2
复合赋值
............................................................................................................................... 158
7.13.3
事件赋值
............................................................................................................................... 159
7.14
表达式
.........................................................................................................................................
159
7.15
常量表达式
.................................................................................................................................
159
7.16
布尔表达式
.................................................................................................................................
160
8.
语句
..................................................................................................................................................
161
8.1
结束点和可到达性
........................................................................................................................
161
8.2
块
..
163
8.2.1
语句列表
................................................................................................................................. 163
8.3
空语句
...........................................................................................................................................
163
8.4
标记语句
.......................................................................................................................................
164
8.5
声明语句
.......................................................................................................................................
164
8.5.1
局部变量声明
......................................................................................................................... 165
8.5.2
局部常量声明
......................................................................................................................... 165
8.6
表达式语句
...................................................................................................................................
166
8.7
选择语句
.......................................................................................................................................
166
8.7.1 if
语句
.....................................................................................................................................
166
8.7.2 switch
语句
..............................................................................................................................
167
8.8
迭代语句
.......................................................................................................................................
171
8.8.1 while
语句
...............................................................................................................................
171
8.8.2 do
语句
....................................................................................................................................
171
8.8.3 for
语句
...................................................................................................................................
172
8.8.4 foreach
语句
............................................................................................................................
173
8.9
跳转语句
.......................................................................................................................................
175
8.9.1 break
语句
...............................................................................................................................
176
8.9.2 continue
语句
...........................................................................................................................
176
8.9.3 goto
语句
.................................................................................................................................
177
8.9.4 return
语句
..............................................................................................................................
178
8.9.5 throw
语句
...............................................................................................................................
178
8.10 try
语句
........................................................................................................................................
179
8.11 checked
语句和
unchecked
语句
.................................................................................................
182
8.12 lock
语句
......................................................................................................................................
182
8.13 using
语句
....................................................................................................................................
183
9.
命名空间
..........................................................................................................................................
185
9.1
编译单元
.......................................................................................................................................
185
9.2
命名空间声明
...............................................................................................................................
185
9.3 using
指令
......................................................................................................................................
186
9.3.1 Using
别名指令
....................................................................................................................... 187
9.3.2 Using
命名空间指令
................................................................................................................ 189
9.4
命名空间成员
...............................................................................................................................
191
9.5
类型声明
.......................................................................................................................................
191
10.
类
....................................................................................................................................................
193
10.1
类声明
.........................................................................................................................................
193
10.1.1
类修饰符
............................................................................................................................... 193
10.1.1.1
抽象类
.............................................................................................................................
194
10.1.1.2
密封类
.............................................................................................................................
194
10.1.2
类基本规格
........................................................................................................................... 194
10.1.2.1
基类
................................................................................................................................
195
10.1.2.2
接口实现
.........................................................................................................................
196
10.1.3
类体
...................................................................................................................................... 196
10.2
类成员
.........................................................................................................................................
196
10.2.1
继承
...................................................................................................................................... 197
10.2.2 new
修饰符
........................................................................................................................... 198
10.2.3
访问修饰符
........................................................................................................................... 198
10.2.4
构成类型
............................................................................................................................... 198
10.2.5
静态成员和实例成员
............................................................................................................ 198
10.2.6
嵌套类型
............................................................................................................................... 199
10.2.6.1
完全限定名
.....................................................................................................................
199
10.2.6.2
已声明可访问性
..............................................................................................................
200
10.2.6.3
隐藏
................................................................................................................................
200
10.2.6.4 this
访问
..........................................................................................................................
201
10.2.6.5
对包含类型的私有和受保护成员的访问
........................................................................
202
10.2.7
保留成员名称
....................................................................................................................... 203
10.2.7.1
为属性保留的成员名称
..................................................................................................
203
10.2.7.2
为事件保留的成员名称
..................................................................................................
204
10.2.7.3
为索引器保留的成员名称
...............................................................................................
204
10.2.7.4
为析构函数保留的成员名称
...........................................................................................
204
10.3
常量
.............................................................................................................................................
204
10.4
字段
.............................................................................................................................................
206
10.4.1
静态字段和实例字段
............................................................................................................ 207
10.4.2
只读字段
............................................................................................................................... 207
10.4.2.1
对常量使用静态只读字段
...............................................................................................
208
10.4.2.2
常量和静态只读字段的版本控制
...................................................................................
208
10.4.3
易失字段
............................................................................................................................... 209
10.4.4
字段初始化
........................................................................................................................... 210
10.4.5
变量初始值设定项
................................................................................................................ 210
10.4.5.1
静态字段初始化
..............................................................................................................
211
10.4.5.2
实例字段初始化
..............................................................................................................
212
10.5
方法
.............................................................................................................................................
213
10.5.1
方法参数
............................................................................................................................... 214
10.5.1.1
值参数
.............................................................................................................................
215
10.5.1.2
引用参数
.........................................................................................................................
215
10.5.1.3
输出参数
.........................................................................................................................
216
10.5.1.4
参数数组
.........................................................................................................................
217
10.5.2
静态方法和实例方法
............................................................................................................ 219
10.5.3
虚方法
................................................................................................................................... 220
10.5.4
重写方法
............................................................................................................................... 222
10.5.5
密封方法
............................................................................................................................... 223
10.5.6
抽象方法
............................................................................................................................... 224
10.5.7
外部方法
............................................................................................................................... 225
10.5.8
方法体
................................................................................................................................... 226
10.5.9
方法重载
............................................................................................................................... 226
10.6
属性
.............................................................................................................................................
226
10.6.1
静态属性和实例属性
............................................................................................................ 227
10.6.2
访问器
................................................................................................................................... 228
10.6.3
虚、密封、重写和抽象访问器
............................................................................................. 232
10.7
事件
.............................................................................................................................................
233
10.7.1
类似字段的事件
.................................................................................................................... 235
10.7.2
事件访问器
........................................................................................................................... 237
10.7.3
静态事件和实例事件
............................................................................................................ 238
10.7.4
虚、密封、重写和抽象访问器
............................................................................................. 238
10.8
索引器
.........................................................................................................................................
238
10.8.1
索引器重载
........................................................................................................................... 242
10.9
运算符
.........................................................................................................................................
242
10.9.1
一元运算符
........................................................................................................................... 243
10.9.2
二元运算符
........................................................................................................................... 244
10.9.3
转换运算符
........................................................................................................................... 244
10.10
实例构造函数
............................................................................................................................
245
10.10.1
构造函数初始值设定项
....................................................................................................... 246
10.10.2
实例变量初始值设定项
....................................................................................................... 247
10.10.3
构造函数执行
...................................................................................................................... 247
10.10.4
默认构造函数
...................................................................................................................... 249
10.10.5
私有构造函数
...................................................................................................................... 250
10.10.6
可选的实例构造函数参数
................................................................................................... 250
10.11
静态构造函数
............................................................................................................................
250
10.12
析构函数
...................................................................................................................................
252
11.
结构
................................................................................................................................................
255
11.1
结构声明
.....................................................................................................................................
255
11.1.1
结构修饰符
........................................................................................................................... 255
11.1.2
结构接口
............................................................................................................................... 256
11.1.3
结构体
................................................................................................................................... 256
11.2
结构成员
.....................................................................................................................................
256
11.3
类和结构的区别
..........................................................................................................................
256
11.3.1
值语义
................................................................................................................................... 257
11.3.2
继承
...................................................................................................................................... 258
11.3.3
赋值
...................................................................................................................................... 258
11.3.4
默认值
................................................................................................................................... 258
11.3.5
装箱和拆箱
........................................................................................................................... 259
11.3.6 this
的含义
............................................................................................................................. 259
11.3.7
字段初始值设定项
................................................................................................................ 259
11.3.8
构造函数
............................................................................................................................... 259
11.3.9
析构函数
............................................................................................................................... 260
11.3.10
静态构造函数
...................................................................................................................... 260
11.4
结构示例
.....................................................................................................................................
261
11.4.1
数据库整数类型
.................................................................................................................... 261
11.4.2
数据库布尔类型
.................................................................................................................... 262
12.
数组
................................................................................................................................................
265
12.1
数组类型
.....................................................................................................................................
265
12.1.1 System.Array
类型
................................................................................................................. 266
12.2
数组创建
.....................................................................................................................................
266
12.3
数组元素访问
..............................................................................................................................
266
12.4
数组成员
.....................................................................................................................................
266
12.5
数组协变
.....................................................................................................................................
266
12.6
数组初始值设定项
......................................................................................................................
267
13.
接口
................................................................................................................................................
269
13.1
接口声明
.....................................................................................................................................
269
13.1.1
接口修饰符
........................................................................................................................... 269
13.1.2
基接口
................................................................................................................................... 269
13.1.3
接口体
................................................................................................................................... 270
13.2
接口成员
.....................................................................................................................................
270
13.2.1
接口方法
............................................................................................................................... 271
13.2.2
接口属性
............................................................................................................................... 272
13.2.3
接口事件
............................................................................................................................... 272
13.2.4
接口索引器
........................................................................................................................... 272
13.2.5
接口成员访问
....................................................................................................................... 272
13.3
完全限定接口成员名
..................................................................................................................
274
13.4
接口实现
.....................................................................................................................................
275
13.4.1
显式接口成员实现
................................................................................................................ 275
13.4.2
接口映射
............................................................................................................................... 277
13.4.3
接口实现继承
....................................................................................................................... 280
13.4.4
接口重新实现
....................................................................................................................... 281
13.4.5
抽象类和接口
....................................................................................................................... 282
14.
枚举
................................................................................................................................................
285
14.1
枚举声明
.....................................................................................................................................
285
14.2
枚举修饰符
.................................................................................................................................
286
14.3
枚举成员
.....................................................................................................................................
286
14.4 System.Enum
类型
.......................................................................................................................
288
14.5
枚举值和运算
..............................................................................................................................
288
15.
委托
................................................................................................................................................
289
15.1
委托声明
.....................................................................................................................................
289
15.2
委托实例化
.................................................................................................................................
291
15.3
委托调用
.....................................................................................................................................
291
16.
异常
................................................................................................................................................
295
16.1
导致异常的原因
..........................................................................................................................
295
16.2 System.Exception
类
.....................................................................................................................
295
16.3
异常的处理方式
..........................................................................................................................
296
16.4
公共异常类
.................................................................................................................................
296
17.
属性
................................................................................................................................................
299
17.1
属性类
.........................................................................................................................................
299
17.1.1
属性用法
............................................................................................................................... 299
17.1.2
定位和命名参数
.................................................................................................................... 300
17.1.3
属性参数类型
....................................................................................................................... 301
17.2
属性专用化
.................................................................................................................................
301
17.3
属性实例
.....................................................................................................................................
306
17.3.1
属性的编译
........................................................................................................................... 306
17.3.2
属性实例的运行时检索
........................................................................................................ 306
17.4
保留属性
.....................................................................................................................................
307
17.4.1 AttributeUsage
属性
............................................................................................................... 307
17.4.2 Conditional
属性
..................................................................................................................... 308
17.4.2.1
条件方法
.........................................................................................................................
308
17.4.2.2
条件属性类
.....................................................................................................................
310
17.4.3 Obsolete
属性
........................................................................................................................ 311
17.5
交互操作的属性
..........................................................................................................................
312
17.5.1
与
COM
和
Win32
组件的交互操作
................................................................................... 312
17.5.2
与其他
.NET
语言的交互操作
............................................................................................. 312
17.5.2.1 IndexerName
属性
...........................................................................................................
312
18.
不安全代码
....................................................................................................................................
313
18.1
不安全上下文
..............................................................................................................................
313
18.2
指针类型
.....................................................................................................................................
315
18.3
固定和可移动变量
......................................................................................................................
318
18.4
指针转换
.....................................................................................................................................
318
18.5
表达式中的指针
..........................................................................................................................
319
18.5.1
指针间接寻址
....................................................................................................................... 320
18.5.2
指针成员访问
....................................................................................................................... 320
18.5.3
指针元素访问
....................................................................................................................... 321
18.5.4 address-of
运算符
.................................................................................................................. 322
18.5.5
指针递增和递减
.................................................................................................................... 323
18.5.6
指针算术运算
....................................................................................................................... 323
18.5.7
指针比较
............................................................................................................................... 324
18.5.8 sizeof
运算符
......................................................................................................................... 324
18.6 fixed
语句
....................................................................................................................................
325
18.7
堆栈分配
.....................................................................................................................................
328
18.8
动态内存分配
..............................................................................................................................
329
A.
文档注释
.........................................................................................................................................
331
A.1.
介绍
............................................................................................................................................
331
A.2.
建议的标记
.................................................................................................................................
332
A.2.1. <c>
333
A.2.2. <code>
...................................................................................................................................
333
A.2.3. <example>
..............................................................................................................................
334
A.2.4. <exception>
............................................................................................................................
334
A.2.5. <include>
................................................................................................................................
335
A.2.6. <list>
......................................................................................................................................
335
A.2.7. <para>
....................................................................................................................................
336
A.2.8. <param>
.................................................................................................................................
337
A.2.9. <paramref>
.............................................................................................................................
337
A.2.10. <permission>
.........................................................................................................................
338
A.2.11. <summary>
...........................................................................................................................
338
A.2.12. <returns>
..............................................................................................................................
338
A.2.13. <see>
....................................................................................................................................
339
A.2.14. <seealso>
..............................................................................................................................
339
A.2.15. <summary>
...........................................................................................................................
340
A.2.16. <value>
.................................................................................................................................
340
A.3.
处理文档文件
.............................................................................................................................
340
A.3.1. ID
字符串格式
......................................................................................................................
341
A.3.2. ID
字符串示例
......................................................................................................................
341
A.4.
示例
............................................................................................................................................
345
A.4.1. C#
源代码
.............................................................................................................................
345
A.4.2.
产生的
XML
.........................................................................................................................
347
B.
语法
.................................................................................................................................................
351
B.1.
词法文法
.....................................................................................................................................
351
B.1.1.
行结束符
............................................................................................................................... 351
B.1.2.
空白
...................................................................................................................................... 351
B.1.3.
注释
...................................................................................................................................... 351
B.1.4.
标记
...................................................................................................................................... 352
B.1.5. Unicode
字符转义序列
.......................................................................................................... 352
B.1.6.
标识符
................................................................................................................................... 353
B.1.7.
关键字
................................................................................................................................... 354
B.1.8.
文本
...................................................................................................................................... 354
B.1.9.
运算符和标点符号
................................................................................................................ 356
B.1.10.
预处理指令
......................................................................................................................... 356
B.2.
句法文法
.....................................................................................................................................
358
B.2.1.
基本概念
............................................................................................................................... 358
B.2.2.
类型
...................................................................................................................................... 358
B.2.3.
变量
...................................................................................................................................... 360
B.2.4.
表达式
................................................................................................................................... 360
B.2.5.
语句
...................................................................................................................................... 363
B.2.6.
命名空间
............................................................................................................................... 366
B.2.7.
类
367
B.2.8.
结构
...................................................................................................................................... 373
B.2.9.
数组
...................................................................................................................................... 374
B.2.10.
接口
..................................................................................................................................... 374
B.2.11.
枚举
..................................................................................................................................... 375
B.2.12.
委托
..................................................................................................................................... 376
B.2.13.
属性
..................................................................................................................................... 376
B.3.
不安全代码的语法扩展
...............................................................................................................
377
C.
参考资料
.........................................................................................................................................
381
19. C# 2.0
简介
........................................................................................................................................
1
19.1
泛型
................................................................................................................................................
1
19.1.1
为什么要使用泛型?
................................................................................................................
1
19.1.2
创建和使用泛型
.......................................................................................................................
2
19.1.3
泛型类型实例化
.......................................................................................................................
3
19.1.4
约束
..........................................................................................................................................
4
19.1.5
泛型方法
..................................................................................................................................
5
19.2
匿名方法
.........................................................................................................................................
6
19.2.1
方法组转换
...............................................................................................................................
8
19.3
迭代器
............................................................................................................................................
8
19.4
分部类型
.......................................................................................................................................
11
19.5
可空类型
.......................................................................................................................................
12
20.
泛型
..................................................................................................................................................
15
20.1
泛型类声明
...................................................................................................................................
15
20.1.1
类型形参
.................................................................................................................................
15
20.1.2
实例类型
.................................................................................................................................
16
20.1.3
基规范
....................................................................................................................................
17
20.1.4
泛型类的成员
.........................................................................................................................
17
20.1.5
泛型类中的静态字段
..............................................................................................................
18
20.1.6
泛型类中的静态构造函数
......................................................................................................
18
20.1.7
访问受保护成员
.....................................................................................................................
19
20.1.8
泛型类中的重载
.....................................................................................................................
19
20.1.9
形参数组方法和类型形参
......................................................................................................
20
20.1.10
重写和泛型类
.......................................................................................................................
20
20.1.11
泛型类中的运算符
................................................................................................................
21
20.1.12
泛型类中的嵌套类型
............................................................................................................
22
20.1.13
应用程序入口点
....................................................................................................................
23
20.2
泛型结构声明
...............................................................................................................................
23
20.3
泛型接口声明
...............................................................................................................................
23
20.3.1
所实现接口的唯一性
..............................................................................................................
23
20.3.2
显式接口成员实现
..................................................................................................................
24
20.4
泛型委托声明
...............................................................................................................................
25
20.5
构造类型
.......................................................................................................................................
25
20.5.1
类型实参
.................................................................................................................................
26
20.5.2
开放和封闭类型
.....................................................................................................................
26
20.5.3
构造类型的基类和接口
..........................................................................................................
27
20.5.4
构造类型的成员
.....................................................................................................................
27
20.5.5
构造类型的可访问性
..............................................................................................................
28
20.5.6
转换
........................................................................................................................................
28
20.5.7 using
别名指令
........................................................................................................................
29
20.5.8
属性
........................................................................................................................................
29
20.5.9
数组和泛型
IList
接口
...........................................................................................................
29
20.6
泛型方法
.......................................................................................................................................
30
20.6.1
泛型方法签名
.........................................................................................................................
31
20.6.2
虚泛型方法
.............................................................................................................................
31
20.6.3
调用泛型方法
.........................................................................................................................
33
20.6.4
类型实参推断
.........................................................................................................................
33
20.6.5
语法多义性
.............................................................................................................................
35
20.6.6
通过委托使用泛型方法
..........................................................................................................
35
20.6.7
不能是泛型的成员
..................................................................................................................
36
20.7
约束
..............................................................................................................................................
36
20.7.1
满足约束
.................................................................................................................................
40
20.7.2
类型形参上的成员查找
..........................................................................................................
41
20.7.3
类型形参和装箱
.....................................................................................................................
41
20.7.4
涉及类型形参的转换
..............................................................................................................
42
20.8
表达式和语句
...............................................................................................................................
44
20.8.1
对象创建表达式
.....................................................................................................................
44
20.8.2 typeof
运算符
..........................................................................................................................
44
20.8.3
引用相等运算符
.....................................................................................................................
45
20.8.4 is
运算符
.................................................................................................................................
46
20.8.5 as
运算符
................................................................................................................................
46
20.8.6
异常语句
.................................................................................................................................
46
20.8.7 lock
语句
.................................................................................................................................
46
20.8.8 using
语句
................................................................................................................................
46
20.8.9 foreach
语句
............................................................................................................................
46
20.9
查找规则的修改
............................................................................................................................
47
20.9.1
命名空间和类型名称
..............................................................................................................
47
20.9.2
成员查找
.................................................................................................................................
49
20.9.3
适用函数成员
.........................................................................................................................
50
20.9.4
更好的函数成员
.....................................................................................................................
50
20.9.5
简单名称
.................................................................................................................................
51
20.9.6
成员访问
.................................................................................................................................
52
20.9.7
方法调用
.................................................................................................................................
54
20.10
右移语法变化
..............................................................................................................................
55
21.
匿名方法
..........................................................................................................................................
57
21.1
匿名方法表达式
............................................................................................................................
57
21.2
匿名方法签名
...............................................................................................................................
57
21.3
匿名方法转换
...............................................................................................................................
57
21.4
匿名方法块
...................................................................................................................................
59
21.5
外层变量
.......................................................................................................................................
59
21.5.1
捕获的外层变量
.....................................................................................................................
59
21.5.2
局部变量实例化
.....................................................................................................................
60
21.6
匿名方法计算
...............................................................................................................................
62
21.7
委托实例相等性
............................................................................................................................
63
21.8
明确赋值
.......................................................................................................................................
63
21.9
方法组转换
...................................................................................................................................
64
21.10
委托创建表达式
..........................................................................................................................
65
21.11
实现示例
.....................................................................................................................................
65
22.
迭代器
..............................................................................................................................................
69
22.1
迭代器块
.......................................................................................................................................
69
22.1.1
枚举器接口
.............................................................................................................................
69
22.1.2
可枚举接口
.............................................................................................................................
69
22.1.3
产生类型
.................................................................................................................................
69
22.1.4 this
访问
..................................................................................................................................
70
22.2
枚举器对象
...................................................................................................................................
70
22.2.1 MoveNext
方法
.......................................................................................................................
70
22.2.2 Current
属性
............................................................................................................................
71
22.2.3 Dispose
方法
...........................................................................................................................
71
22.3
可枚举对象
...................................................................................................................................
72
22.3.1 GetEnumerator
方法
.................................................................................................................
72
22.4 yield
语句
.......................................................................................................................................
72
22.4.1
明确赋值
.................................................................................................................................
74
22.5
实现示例
.......................................................................................................................................
74
23.
分部类型
..........................................................................................................................................
81
23.1
分部声明
.......................................................................................................................................
81
23.1.1
属性
........................................................................................................................................
81
23.1.2
修饰符
....................................................................................................................................
82
23.1.3
类型参数和约束
.....................................................................................................................
82
23.1.4
基类
........................................................................................................................................
82
23.1.5
基接口
....................................................................................................................................
83
23.1.6
成员
........................................................................................................................................
83
23.2
名称绑定
.......................................................................................................................................
84
24.
可空类型
..........................................................................................................................................
85
24.1
可空类型
.......................................................................................................................................
85
24.1.1
成员
........................................................................................................................................
85
24.1.2
默认值
....................................................................................................................................
86
24.1.3
值类型约束
.............................................................................................................................
86
24.2
转换
..............................................................................................................................................
86
24.2.1 null
文本转换
...........................................................................................................................
86
24.2.2
可空转换
.................................................................................................................................
86
24.2.3
装箱和取消装箱转换
..............................................................................................................
87
24.2.4
允许的用户定义转换
..............................................................................................................
87
24.2.5
用户定义转换的计算
..............................................................................................................
88
24.2.6
提升的转换
.............................................................................................................................
88
24.2.7
用户定义的隐式转换
..............................................................................................................
88
24.2.8
用户定义的显式转换
..............................................................................................................
89
24.3
表达式
...........................................................................................................................................
90
24.3.1
提升运算符
.............................................................................................................................
90
24.3.2
允许的用户定义运算符
..........................................................................................................
91
24.3.3
运算符重载解析
.....................................................................................................................
91
24.3.4
相等操作符和空
.....................................................................................................................
91
24.3.5 is
运算符
.................................................................................................................................
91
24.3.6 as
运算符
................................................................................................................................
92
24.3.7
复合赋值
.................................................................................................................................
92
24.3.8 bool?
类型
...............................................................................................................................
92
24.3.9
空合并运算符
.........................................................................................................................
93
25.
其他功能
..........................................................................................................................................
95
25.1
属性访问器的可访问性
................................................................................................................
95
25.1.1
访问器声明
.............................................................................................................................
95
25.1.2
访问器的使用
.........................................................................................................................
96
25.1.3
重写和接口实现
.....................................................................................................................
97
25.2
静态类
...........................................................................................................................................
97
25.2.1
静态类声明
.............................................................................................................................
97
25.2.2
引用静态类类型
.....................................................................................................................
98
25.3
命名空间别名限定符
....................................................................................................................
98
25.3.1
限定的别名成员
....................................................................................................................
100
25.3.2
别名的唯一性
.......................................................................................................................
101
25.4 Extern
别名
..................................................................................................................................
102
25.4.1 Extern
别名指令
....................................................................................................................
103
25.5 Pragma
指令
................................................................................................................................
104
25.5.1 Pragma warning......................................................................................................................
105
25.6
默认值表达式
..............................................................................................................................
105
25.7
条件属性类
.................................................................................................................................
106
25.8
固定大小缓冲区
..........................................................................................................................
107
25.8.1
固定大小缓冲区的声明
........................................................................................................
107
25.8.2
表达式中的固定大小缓冲区
.................................................................................................
108
25.8.3 Fixed
语句
.............................................................................................................................
109
25.8.4
明确赋值检查
.......................................................................................................................
109
C#
(
读作
“
See Sharp
”)
是一种简单、现代、面向对象且类型安全的编程语言。
C#
起源于
C
语言家族,因此,对于
C
、
C++
和
Java
程序员,可以很快熟悉这种新的语言。
C#
已经分别由
ECMA International
和
ISO/IEC
组织接受并确立了标准
,
它们分别是
ECMA-334
标准和
ISO/IEC 23270
标准。
Microsoft
用于
.NET Framework
的
C#
编译器就是根据这两个标准实现的。
C#
是面向对象的语言
,
然而
C#
进一步提供了对面向组件
(component-oriented)
编程的支持。现代软件设计日益依赖于自包含和自描述功能包形式的软件组件。这种组件的关键在于
,
它们通过属性
(property)
、方法
(method)
和事件
(event)
来提供编程模型
;
它们具有提供了关于组件的声明性信息的属性
(attribute)
;
同时
,
它们还编入了自己的文档。
C#
提供的语言构造直接支持这些概念,这使得
C#
语言自然而然成为创建和使用软件组件之选。
C#
的一些特性为构造强健和持久的应用程序提供了支持
:
垃圾回收
(Garbage collection)
将自动回收不再使用的对象所占用的内存
;
异常处理
(exception handling)
提供了结构化和可扩展的错误检测和恢复方法
;
类型安全
(type-safe)
的语言设计则避免了引用未初始化的变量、数组索引超出边界或执行未经检查的类型强制转换等情形。
C#
具有一个统一类型系统
(unified type system)
。所有
C#
类型
(
包括诸如
int
和
double
之类的基元类型
)
都继承于一个唯一的根类型
:
object
。因此,所有类型都共享一组通用操作,并且任何类型的值都能够以一致的方式进行存储、传递和操作。此外,
C#
同时支持用户定义的引用类型和值类型,既允许对象的动态分配,也允许轻量结构的内联存储。
为了确保
C#
程序和库能够以兼容的方式逐步演进
,
C#
的设计中充分强调了版本控制
(versioning)
。许多编程语言不太重视这一点,导致采用那些语言编写的程序常常因为其所依赖的库的更新而无法正常工作。
C#
的设计在某些方面直接考虑到版本控制的需要,其中包括单独使用的
virtual
和
override
修饰符、方法重载决策规则以及对显式接口成员声明的支持。
本章的其余部分将描述
C#
语言的基本特征。尽管后面的章节会更为详尽,有时甚至逻辑缜密地对规则和例外情况进行描述,但本章的描述力求简洁明了,因而难免会牺牲完整性。这样做是为了向读者提供关于该语言的概貌,一方面使读者能尽快上手编写程序,另一方面为阅读后续章节提供指导。
按照约定俗成的惯例
,
我们先从
“
Hello, World
”
程序着手介绍这一编程语言。下面是它的
C#
程序
:
using System;
class Hello
{
static void
Main
() {
Console.WriteLine("Hello, World");
}
}
C#
源文件的扩展名通常是
.cs
。假定
“
Hello, World
”
程序存储在文件
hello.cs
中
,
可以使用下面的命令行调用
Microsoft C#
编译器编译这个程序
:
csc hello.cs
编译后将产生一个名为
hello.exe
的可执行程序集。当此应用程序运行时,输出结果如下:
Hello, World
“
Hello, World
”
程序的开头是一个
using
指令
,
它引用了
System
命名空间。命名空间
(namespace)
提供了一种分层的方式来组织
C#
程序和库。命名空间中包含有类型及其他命名空间
—
例如
,
System
命名空间包含若干类型
(
如此程序中引用的
Console
类
)
以及若干其他命名空间
(
如
IO
和
Collections
)
。如果使用
using
指令引用了某一给定命名空间,就可以通过非限定方式使用作为命名空间成员的类型。在此程序中
,
正是由于使用了
using
指令
,
我们可以使用
Console.WriteLine
这一简化形式代替完全限定方式
System.Console.WriteLine
。
“
Hello, World
”
程序中声明的
Hello
类只有一个成员
,
即名为
Main
的方法。
Main
方法是使用
static
修饰符声明的。静态
(static)
方法不同于实例
(instance)
方法
,
后者使用关键字
this
来引用特定的对象实例
,
而静态方法的操作不需要引用特定对象。按照惯例,名为
Main
的静态方法将作为程序的入口点。
该程序的输出由
System
命名空间中的
Console
类的
WriteLine
方法产生。此类由
.NET Framework
类库提供
,
默认情况下
,
Microsoft C#
编译器自动引用该类库。注意,
C#
语言本身不具有单独的运行时库。事实上
,
.NET Framework
就是
C#
的运行时库。
C#
中的组织结构的关键概念是程序
(program)
、命名空间
(namespace)
、类型
(type)
、成员
(member)
和程序集
(assembly)
。
C#
程序由一个或多个源文件组成。程序中声明类型,类型包含成员,并且可按命名空间进行组织。类和接口就是类型的示例。字段
(field)
、方法、属性和事件是成员的示例。在编译
C#
程序时,它们被物理地打包为程序集。程序集通常具有文件扩展名
.exe
或
.dll
,
具体取决于它们是实现应用程序
(application)
还是实现库
(library)
。
在以下示例中
:
using System;
namespace Acme.Collections
{
public class Stack
{
Entry top;
public void Push(object data) {
top = new Entry(top, data);
}
public object Pop() {
if (top == null) throw new InvalidOperationException();
object result = top.data;
top = top.next;
return result;
}
class Entry
{
public Entry next;
public object data;
public Entry(Entry next, object data) {
this.next = next;
this.data = data;
}
}
}
}
在名为
Acme.Collections
的命名空间中声明了一个名为
Stack
的类。这个类的完全限定名为
Acme.Collections.Stack
。此类中包含以下几个成员
:
一个名为
top
的字段
,
两个分别名为
Push
和
Pop
的方法和一个名为
Entry
的嵌套类。
Entry
类又进一步包含三个成员
:
一个名为
next
的字段
,
一个名为
data
的字段和一个构造函数。假定将此示例的源代码存储在文件
acme.cs
中,执行以下命令行:
csc /t:library acme.cs
将此示例编译为一个库
(
没有
Main
入口点的代码
),
并产生一个名为
acme.dll
的程序集。
程序集包含中间语言
(Intermediate Language, IL)
指令形式的可执行代码和元数据
(metadata)
形式的符号信息。在执行程序集之前,
.NET
公共语言运行库的实时
(JIT)
编译器将程序集中的
IL
代码自动转换为特定于处理器的代码。
由于程序集是一个自描述的功能单元
,
它既包含代码又包含元数据
,
因此
,
C#
中不需要
#include
指令和头文件。若要在
C#
程序中使用某特定程序集中包含的公共类型和成员,只需在编译程序时引用该程序集即可。例如
,
下面程序使用来自
acme.dll
程序集的
Acme.Collections.Stack
类
:
using System;
using Acme.Collections;
class Test
{
static void Main() {
Stack s = new Stack();
s.Push(1);
s.Push(10);
s.Push(100);
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop());
}
}
如果此程序存储在文件
test.cs
中
,
那么在编译
test.cs
时
,
可以使用编译器的
/r
选项引用
acme.dll
程序集
:
csc /r:acme.dll test.cs
这样将创建名为
test.exe
的可执行程序集
,
运行结果如下
:
100
10
1
C#
允许将一个程序的源文本存储在多个源文件中。在编译多个文件组成的
C#
程序时,所有源文件将一起处理,并且源文件可以自由地相互引用
—
从概念上讲,就像是在处理之前将所有源文件合并为一个大文件。
C#
中从不需要前向声明,因为除了极少数的例外情况,声明顺序无关紧要。
C#
不限制一个源文件只能声明一个公共类型,也不要求源文件的名称与该源文件中声明的类型匹配。
C#
中有两种类型
:
值类型
(value type)
和引用类型
(reference type)
。
值类型的变量直接包含它们的数据
,
而引用类型的变量存储对它们的数据的引用
,
后者称为对象。对于引用类型,两个变量可能引用同一个对象,因此对一个变量的操作可能影响另一个变量所引用的对象。对于值类型,每个变量都有它们自己的数据副本(除
ref
和
out
参数变量外),因此对一个变量的操作不可能影响另一个变量。
C#
的值类型进一步划分为简单类型
(simple type)
、枚举类型
(enum type)
和结构类型
(struct type)
,
C#
的引用类型进一步划分为类类型
(class type)
、接口类型
(interface type)
、数组类型
(array type)
和委托类型
(delegate type)
。
下表为
C#
类型系统的概述。
类别
|
说明
|
值类型
|
简单类型
|
有符号整型
:
sbyte
,
short
,
int
,
long
|
无符号整型
:
byte
,
ushort
,
uint
,
ulong
|
Unicode
字符
:
char
|
IEEE
浮点型
:
float
,
double
|
高精度小数
:
decimal
|
布尔型
:
bool
|
枚举类型
|
enum E {...}
形式的用户定义的类型
|
结构类型
|
struct S {...}
形式的用户定义的类型
|
引用类型
|
类类型
|
所有其他类型的最终基类
:
object
|
Unicode
字符串
:
string
|
class
C
{...}
形式的用户定义的类型
|
接口类型
|
interface I {...}
形式的用户定义的类型
|
数组类型
|
一维和多维数组
,
例如
int[]
和
int[,]
|
委托类型
|
delegate T D(...)
形式的用户定义的类型
|
八种整型类型分别支持
8
位、
16
位、
32
位和
64
位整数值的有符号和无符号的形式。
两种浮点类型
:
float
和
double
,
分别使用
32
位单精度和
64
位双精度的
IEEE 754
格式表示。
decimal
类型是
128
位的数据类型
,
适合用于财务计算和货币计算。
C#
的
bool
类型用于表示布尔值
—
为
true
或者
false
的值。
在
C#
中
,
字符和字符串处理使用
Unicode
编码。
char
类型表示一个
16
位
Unicode
编码单元
,
string
类型表示
16
位
Unicode
编码单元的序列。
下表总结了
C#
的数值类型。
类别
|
位数
|
类型
|
范围
/
精度
|
有符号整型
|
8
|
sbyte
|
–128...127
|
16
|
short
|
–32,768...32,767
|
32
|
int
|
–2,147,483,648...2,147,483,647
|
64
|
long
|
–9,223,372,036,854,775,808...9,223,372,036,854,775,807
|
无符号整型
|
8
|
byte
|
0...255
|
16
|
ushort
|
0...65,535
|
32
|
uint
|
0...4,294,967,295
|
64
|
ulong
|
0...18,446,744,073,709,551,615
|
浮点数
|
32
|
float
|
1.5 × 10−45
至
3.4 × 1038
,
7
位精度
|
64
|
double
|
5.0 × 10−324
至
1.7 × 10308
,
15
位精度
|
小数
|
128
|
decimal
|
1.0 × 10−28
至
7.9 × 1028
,
28
位精度
|
C#
程序使用类型声明
(type declaration)
创建新类型。类型声明指定新类型的名称和成员。有五种类别的
C#
类型是可由用户定义的:类类型、结构类型、接口类型、枚举类型和委托类型。
类类型定义了一个包含数据成员
(
字段
)
和函数成员
(
方法、属性等
)
的数据结构。类类型支持继承和多态,这些是派生类可用来扩展和专用化基类的一种机制。
结构类型与类类型相似
,
表示一个带有数据成员和函数成员的结构。但是,与类不同,结构是一种值类型,并且不需要堆分配。结构类型不支持用户指定的继承,并且所有结构类型都隐式地从类型
object
继承。
接口类型定义了一个协定
,
作为一个函数成员的命名集合。实现某个接口的类或结构必须提供该接口的函数成员的实现。一个接口可以从多个基接口继承,而一个类或结构可以实现多个接口。
枚举类型是具有命名常量的独特的类型。每种枚举类型都具有一个基础类型,该基础类型必须是八种整型之一。枚举类型的值集和它的基础类型的值集相同。
委托类型表示对具有特定参数列表和返回类型的方法的引用。通过委托,我们能够将方法作为实体赋值给变量和作为参数传递。委托类似于在其他某些语言中的函数指针的概念,但是与函数指针不同,委托是面向对象的,并且是类型安全的。
C#
支持由任何类型组成的一维和多维数组。与其他类型不同,数组类型不必在使用之前事先声明。实际上,数组类型是通过在某个类型名后加一对方括号来构造的。例如,
int[]
是一维
int
数组,
int[,]
是二维
int
数组,
int[][]
是一维
int
数组的一维数组。
C#
的类型系统是统一的
,
因此任何类型的值都可以按对象处理。
C#
中的每个类型直接或间接地从
object
类类型派生
,
而
object
是所有类型的最终基类。引用类型的值都被当作“对象”来处理,这是因为这些值可以简单地被视为是属于
object
类型。值类型的值则通过执行装箱
(boxing)
和拆箱
(unboxing)
操作亦按对象处理。下面的示例将
int
值转换为
object
,
然后又转换回
int
。
using System;
class Test
{
static void
Main
() {
int i = 123;
object o = i; // Boxing
int j = (int)o; // Unboxing
}
}
当将值类型的值转换为类型
object
时
,
将分配一个对象实例
(
也称为
“
箱子
”)以
包含该值
,
并将值复制到该箱子中。反过来,当将一个
object
引用强制转换为值类型时,将检查所引用的对象是否含有正确的值类型,如果是,则将箱子中的值复制出来。
C#
的统一类型系统实际上意味着值类型可以
“
按需
”
转换为对象。由于这种统一性
,
使用
object
类型的通用库
(
例如
.NET Framework
中的集合类
)
既可以用于引用类型
,
又可以用于值类型。
C#
中存在几种变量
(variable)
,
包括字段、数组元素、局部变量和参数。变量表示了存储位置,并且每个变量都有一个类型,以决定什么样的值能够存入变量,如下表所示。
变量类型
|
可能的内容
|
值类型
|
类型完全相同的值
|
object
|
空引用、对任何引用类型的对象的引用
,
或对任何值类型的装箱值的引用
|
类类型
|
空引用、对该类类型的实例的引用
,
或者对从该类类型派生的类的实例的引用
|
接口类型
|
空引用、对实现该接口类型的类类型的实例的引用
,
或者对实现该接口类型的值类型的装箱值的引用
|
数组类型
|
空引用、对该数组类型的实例的引用
,
或者对兼容数组类型的实例的引用
|
委托类型
|
空引用或对该委托类型的实例的引用
|
表达式
(expression)
由操作数
(operand)
和运算符
(operator)
构成。表达式的运算符指示对操作数进行什么样的运算。运算符的示例包括
+
、
-
、
*
、
/
和
new
。操作数的示例包括文本
(literal)
、字段、局部变量和表达式。
当表达式包含多个运算符时
,
运算符的优先级
(precedence)
控制各运算符的计算顺序。例如,表达式
x + y * z
按
x + (y * z)
计算,因为
*
运算符的优先级高于
+
运算符。
大多数运算符都可以重载
(overload)
。运算符重载允许指定用户定义的运算符实现来执行运算
,
这些运算的操作数中至少有一个
,
甚至所有都属于用户定义的类类型或结构类型。
下表总结了
C#
运算符
,
并按优先级从高到低的顺序列出各运算符类别。同一类别中的运算符优先级相同。
类别
|
表达式
|
说明
|
基本
|
x.m
|
成员访问
|
x(...)
|
方法和委托调用
|
x[...]
|
数组和索引器访问
|
x++
|
后增量
|
x--
|
后减量
|
new T(...)
|
对象和委托创建
|
new T[...]
|
数组创建
|
typeof(T)
|
获得
T
的
System.Type
对象
|
checked(x)
|
在
checked
上下文中计算表达式
|
unchecked(x)
|
在
unchecked
上下文中计算表达式
|
一元
|
+x
|
表达式的值相同
|
-x
|
求相反数
|
!x
|
逻辑求反
|
~x
|
按位求反
|
++x
|
前增量
|
--x
|
前减量
|
(T)x
|
显式将
x
转换为类型
T
|
乘除
|
x * y
|
乘法
|
x / y
|
除法
|
x % y
|
求余
|
加减
|
x + y
|
加法、字符串串联、委托组合
|
x – y
|
减法、委托移除
|
移位
|
x << y
|
左移
|
x >> y
|
右移
|
关系和类型检测
|
x < y
|
小于
|
x > y
|
大于
|
x <= y
|
小于或等于
|
x >= y
|
大于或等于
|
x is T
|
如果
x
属于
T
类型
,
则返回
true
,
否则返回
false
|
x as T
|
返回转换为类型
T
的
x
,
如果
x
不是
T
则返回
null
|
相等
|
x == y
|
等于
|
x != y
|
不等于
|
逻辑
AND
|
x & y
|
整型按位
AND
,
布尔逻辑
AND
|
逻辑
XOR
|
x ^ y
|
整型按位
XOR
,
布尔逻辑
XOR
|
逻辑
OR
|
x | y
|
整型按位
OR
,
布尔逻辑
OR
|
条件
AND
|
x && y
|
仅当
x
为
true
才对
y
求值
|
条件
OR
|
x || y
|
仅当
x
为
false
才对
y
求值
|
条件
|
x ? y : z
|
如果
x
为
true
,
则对
y
求值
,
如果
x
为
false
,
则对
z
求值
|
赋值
|
x = y
|
赋值
|
x
op
=
y
|
复合赋值
;
支持的运算符有
:
*=
/=
%=
+=
-=
<<=
>>=
&=
^=
|=
|
程序的操作是使用语句
(statement)
来表示的。
C#
支持几种不同的语句
,
其中许多以嵌入语句的形式定义。
块
(block)
用于在只允许使用单个语句的上下文中编写多条语句。块由位于一对大括号
{
和
}
之间的语句列表组成。
声明语句
(declaration statement)
用于声明局部变量和常量
。
表达式语句
(expression statement)
用于对表达式求值。可用作语句的表达式包括方法调用、使用
new
运算符的对象分配、使用
=
和复合赋值运算符的赋值
,
以及使用
++
和
--
运算符的增量和减量运算。
选择语句
(selection statement)
用于根据表达式的值从若干个给定的语句中选择一个来执行。这一组语句有
if
和
switch
语句。
迭代语句
(iteration statement)
用于重复执行嵌入语句。这一组语句有
while
、
do
、
for
和
foreach
语句。
跳转语句
(jump statement)
用于转移控制。这一组语句有
break
、
continue
、
goto
、
throw
和
return
语句。
try
...
catch
语句用于捕获在块的执行期间发生的异常
,
try
...
finally
语句用于指定终止代码
,
不管是否发生异常
,
该代码都始终要执行。
checked
语句和
unchecked
语句用于控制整型算术运算和转换的溢出检查上下文。
lock
语句用于获取某个给定对象的互斥锁
,
执行一个语句
,
然后释放该锁。
using
语句用于获得一个资源
,
执行一个语句
,
然后释放该资源。
下表列出了
C#
的各语句
,
并提供每个语句的示例。
语句
|
示例
|
局部变量声明
|
static void
Main
() { int a; int b = 2, c = 3; a = 1; Console.WriteLine(a + b + c); }
|
局部常量声明
|
static void
Main
() { const float pi =
3.1415927f
; const int r = 25; Console.WriteLine(pi * r * r); }
|
表达式语句
|
static void
Main
() { int i; i = 123; // Expression statement Console.WriteLine(i); // Expression statement i++; // Expression statement Console.WriteLine(i); // Expression statement }
|
if
语句
|
static void
Main
(string[] args) { if (args.Length == 0) { Console.WriteLine("No arguments"); } else { Console.WriteLine("One or more arguments"); } }
|
switch
语句
|
static void
Main
(string[] args) { int n = args.Length; switch (n) { case 0: Console.WriteLine("No arguments"); break; case 1: Console.WriteLine("One argument"); break; default: Console.WriteLine("{0} arguments", n); break; } } }
|
while
语句
|
static void
Main
(string[] args) { int i = 0; while (i < args.Length) { Console.WriteLine(args[i]); i++; } }
|
do
语句
|
static void
Main
() { string s; do { s = Console.ReadLine(); if (s != null) Console.WriteLine(s); } while (s != null); }
|
for
语句
|
static void
Main
(string[] args) { for (int i = 0; i < args.Length; i++) { Console.WriteLine(args[i]); } }
|
foreach
语句
|
static void
Main
(string[] args) { foreach (string s in args) { Console.WriteLine(s); } }
|
break
语句
|
static void
Main
() { while (true) { string s = Console.ReadLine(); if (s == null) break; Console.WriteLine(s); } }
|
continue
语句
|
static void
Main
(string[] args) { for (int i = 0; i < args.Length; i++) { if (args[i].StartsWith("/")) continue; Console.WriteLine(args[i]); } }
|
goto
语句
|
static void
Main
(string[] args) { int i = 0; goto check; loop: Console.WriteLine(args[i++]); check: if (i < args.Length) goto loop; }
|
return
语句
|
static int Add(int a, int b) { return a + b; }
static void
Main
() { Console.WriteLine(Add(1, 2)); return; }
|
throw
和
try
语句
|
static double Divide(double x, double y) { if (y == 0) throw new DivideByZeroException(); return x / y; }
static void
Main
(string[] args) { try { if (args.Length != 2) { throw new Exception("Two numbers required"); } double x = double.Parse(args[0]); double y = double.Parse(args[1]); Console.WriteLine(Divide(x, y)); } catch (Exception e) { Console.WriteLine(e.Message); } }
|
checked
和
unchecked
语句
|
static void
Main
() { int i = int.MaxValue; checked { Console.WriteLine(i + 1); // Exception } unchecked { Console.WriteLine(i + 1); // Overflow } }
|
lock
语句
|
class Account { decimal balance;
public void Withdraw(decimal amount) { lock (this) { if (amount > balance) { throw new Exception("Insufficient funds"); } balance -= amount; } } }
|
using
语句
|
static void
Main
() { using (TextWriter w = File.CreateText("test.txt")) { w.WriteLine("Line one"); w.WriteLine("Line two"); w.WriteLine("Line three"); } }
|
类
(class)
是最基础的
C#
类型。类是一个数据结构
,
将状态
(
字段
)
和操作
(
方法和其他函数成员
)
组合在一个单元中。类为动态创建的类实例
(instance)
提供了定义
,
实例也称为对象
(object)
。类支持继承
(inheritance)
和多态性
(polymorphism)
,
这是派生类
(derived class)
可用来扩展和专用化基类
(base class)
的机制。
使用类声明可以创建新的类。类声明以一个声明头开始
,
其组成方式如下
:
先指定类的属性和修饰符
,
然后是类的名称
,
接着是基类
(
如有
)
以及该类实现的接口。声明头后面跟着类体,它由一组位于一对大括号
{
和
}
之间的成员声明组成。
下面是一个名为
Point
的简单类的声明
:
public class Point
{
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
类的实例使用
new
运算符创建
,
该运算符为新的实例分配内存
,
调用构造函数初始化该实例
,
并返回对该实例的引用。下面的语句创建两个
Point
对象,并将对这两个对象的引用存储在两个变量中:
Point p1 = new Point(0, 0);
Point p2 = new Point(10, 20);
当不再使用对象时
,
该对象占用的内存将自动收回。在
C#
中,没有必要也不可能显式释放分配给对象的内存。
类的成员或者是静态成员
(static member)
,
或者是实例成员
(instance member)
。静态成员属于类
,
实例成员属于对象
(
类的实例
)
。
下表提供了类所能包含的成员种类的概述。
成员
|
说明
|
常量
|
与类关联的常数值
|
字段
|
类的变量
|
方法
|
类可执行的计算和操作
|
属性
|
与读写类的命名属性相关联的操作
|
索引器
|
与以数组方式索引类的实例相关联的操作
|
事件
|
可由类生成的通知
|
运算符
|
类所支持的转换和表达式运算符
|
构造函数
|
初始化类的实例或类本身所需的操作
|
析构函数
|
在永久丢弃类的实例之前执行的操作
|
类型
|
类所声明的嵌套类型
|
类的每个成员都有关联的可访问性
,
它控制能够访问该成员的程序文本区域。有五种可能的可访问性形式。下表概述了这些可访问性。
可访问性
|
含义
|
public
|
访问不受限制
|
protected
|
访问仅限于此类和从此类派生的类
|
internal
|
访问仅限于此程序
|
protected internal
|
访问仅限于此程序和从此类派生的类
|
private
|
访问仅限于此类
|
类声明可通过在类名称后面加上一个冒号和基类的名称来指定一个基类。省略基类的指定等同于从类型
object
派生。在下面的示例中
,
Point3D
的基类为
Point
,
而
Point
的基类为
object
:
public class Point
{
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Point3D: Point
{
public int z;
public Point3D(int x, int y, int z): Point(x, y) {
this.z = z;
}
}
一个类继承它的基类的成员。继承意味着一个类隐式地包含其基类的所有成员
,
但基类的构造函数除外。派生类能够在继承基类的基础上添加新的成员,但是它不能移除继承成员的定义。在前面的示例中
,
Point3D
类从
Point
类继承了
x
字段和
y
字段
,
每个
Point3D
实例都包含三个字段
x
、
y
和
z
。
从某个类类型到它的任何基类类型存在隐式的转换。因此,类类型的变量可以引用该类的实例或任何派生类的实例。例如
,
对于前面给定的类声明
,
Point
类型的变量既可以引用
Point
也可以引用
Point3D
:
Point a = new Point(10, 20);
Point b = new Point3D(10, 20, 30);
字段是与类或类的实例关联的变量。
使用
static
修饰符声明的字段定义了一个静态字段
(static field)
。一个静态字段只标识一个存储位置。对一个类无论创建了多少个实例
,
它的静态字段永远都只有一个副本。
不使用
static
修饰符声明的字段定义了一个实例字段
(instance field)
。类的每个实例都包含了该类的所有实例字段的一个单独副本。
在下面的示例中
,
Color
类的每个实例都有实例字段
r
、
g
和
b
的单独副本
,
但是
Black
、
White
、
Red
、
Green
和
Blue
静态字段只存在一个副本
:
public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);
private byte r, g, b;
public Color(byte r, byte g, byte b) {
this.r = r;
this.g = g;
this.b = b;
}
}
如上面的示例所示
,
可以使用
readonly
修饰符声明只读字段
(read-only field)
。给
readonly
字段的赋值只能作为字段声明的组成部分出现
,
或在同一类中的实例构造函数或静态构造函数中出现。
方法
(method)
是一种用于实现可以由对象或类执行的计算或操作的成员。静态方法
(static method)
通过类来访问。实例方法
(instance method)
通过类的实例来访问。
方法具有一个参数
(parameter)
列表
(
可能为空
),
表示传递给该方法的值或变量引用
;
方法还具有一个返回类型
(return type)
,
指定该方法计算和返回的值的类型。如果方法不返回值,则其返回类型为
void
。
方法的签名
(signature)
在声明该方法的类中必须唯一。方法的签名由方法的名称及其参数的数目、修饰符和类型组成。方法的签名不包含返回类型。
参数用于向方法传递值或变量引用。方法的参数从方法被调用时指定的实参
(argument)
获取它们的实际值。有四种类型的参数:值参数、引用参数、输出参数和参数数组。
值参数
(value parameter)
用于输入参数的传递。一个值参数相当于一个局部变量
,
只是它的初始值来自为该形参传递的实参。对值参数的修改不影响为该形参传递的实参。
引用参数
(reference parameter)
用于输入和输出参数传递。为引用参数传递的实参必须是变量,并且在方法执行期间,引用参数与实参变量表示同一存储位置。引用参数使用
ref
修饰符声明。下面的示例演示
ref
参数的使用。
using System;
class Test
{
static void Swap(ref int x, ref int y) {
int temp = x;
x = y;
y = temp;
}
static void
Main
() {
int i = 1, j = 2;
Swap(ref i, ref j);
Console.WriteLine("{0} {1}", i, j); // Outputs "2 1"
}
}
输出参数
(output parameter)
用于输出参数的传递。对于输出参数来说
,
调用方提供的实参的初始值并不重要
,
除此之外
,
输出参数与引用参数类似。输出参数是用
out
修饰符声明的。下面的示例演示
out
参数的使用。
using System;
class Test
{
static void Divide(int x, int y, out int result, out int remainder) {
result = x / y;
remainder = x % y;
}
static void
Main
() {
int res, rem;
Divide(10, 3, out res, out rem);
Console.WriteLine("{0} {1}", res, rem); // Outputs "3 1"
}
}
参数数组
(parameter array)
允许向方法传递可变数量的实参。参数数组使用
params
修饰符声明。只有方法的最后一个参数才可以是参数数组,并且参数数组的类型必须是一维数组类型。
System.Console
类的
Write
和
WriteLine
方法就是参数数组用法的很好示例。它们的声明如下。
public class Console
{
public static void Write(string fmt, params object[] args) {...}
public static void WriteLine(string fmt, params object[] args) {...}
...
}
在使用参数数组的方法中
,
参数数组的行为完全就像常规的数组类型参数。但是,在具有参数数组的方法的调用中,既可以传递参数数组类型的单个实参,也可以传递参数数组的元素类型的任意数目的实参。在后一种情况下,将自动创建一个数组实例,并使用给定的实参对它进行初始化。示例
:
Console.WriteLine("x={0} y={1} z={2}", x, y, z);
等价于写下面的语句。
object[] args = new object[3];
args[0] = x;
args[1] = y;
args[2] = z;
Console.WriteLine("x={0} y={1} z={2}", args);
方法体指定了在该方法被调用时将执行的语句。
方法体可以声明仅用在该方法调用中的变量。这样的变量称为局部变量
(local variable)
。局部变量声明指定了类型名称、变量名称,还可指定初始值。下面的示例声明一个初始值为零的局部变量
i
和一个没有初始值的变量
j
。
using System;
class Squares
{
static void
Main
() {
int i = 0;
int j;
while (i < 10) {
j = i * i;
Console.WriteLine("{0} x {0} = {1}", i, j);
i = i + 1;
}
}
}
C#
要求在对局部变量明确赋值
(definitely assigned)
之后才能获取其值。例如
,
如果前面的
i
的声明未包括初始值
,
则编译器将对随后对
i
的使用报告错误
,
因为
j
在程序中的该位置还没有明确赋值。
方法可以使用
return
语句将控制返回到它的调用方。在返回
void
的方法中
,
return
语句不能指定表达式。在返回非
void
的方法中,
return
语句必须含有一个计算返回值的表达式。
使用
static
修饰符声明的方法为静态方法
(static method)
。静态方法不对特定实例进行操作
,
并且只能访问静态成员。
不使用
static
修饰符声明的方法为实例方法
(instance method)
。实例方法对特定实例进行操作
,
并且能够访问静态成员和实例成员。在调用实例方法的实例上,可以通过
this
显式地访问该实例。而在静态方法中引用
this
是错误的。
下面的
Entity
类具有静态成员和实例成员。
class Entity
{
static int nextSerialNo;
int serialNo;
public Entity() {
serialNo = nextSerialNo++;
}
public int GetSerialNo() {
return serialNo;
}
public static int GetNextSerialNo() {
return nextSerialNo;
}
public static void SetNextSerialNo(int value) {
nextSerialNo = value;
}
}
每个
Entity
实例都包含一个序号
(
并且假定这里省略了一些其他信息
)
。
Entity
构造函数(类似于实例方法)使用下一个可用的序号初始化新的实例。由于该构造函数是一个实例成员
,
它既可以访问
serialNo
实例字段
,
也可以访问
nextSerialNo
静态字段。
GetNextSerialNo
和
SetNextSerialNo
静态方法可以访问
nextSerialNo
静态字段
,
但是如果访问
serialNo
实例字段就会产生错误。
下面的示例演示
Entity
类的使用。
using System;
class Test
{
static void
Main
() {
Entity.SetNextSerialNo(1000);
Entity e1 = new Entity();
Entity e2 = new Entity();
Console.WriteLine(e1.GetSerialNo()); // Outputs "1000"
Console.WriteLine(e2.GetSerialNo()); // Outputs "1001"
Console.WriteLine(Entity.GetNextSerialNo()); // Outputs "1002"
}
}
注意
:
SetNextSerialNo
和
GetNextSerialNo
静态方法是在类上调用的
,
而
GetSerialNo
实例方法是在该类的实例上调用的。
若一个实例方法的声明中含有
virtual
修饰符
,
则称该方法为虚方法
(virtual method)
。若其中没有
virtual
修饰符
,
则称该方法为非虚方法
(non-virtual method)
。
在调用一个虚方法时
,
该调用所涉及的那个实例的运行时类型
(runtime type)
确定了要被调用的究竟是该方法的哪一个实现。在非虚方法调用中
,
实例的编译时类型
(compile-time type)
是决定性因素。
虚方法可以在派生类中重写
(override)
。当某个实例方法声明包括
override
修饰符时
,
该方法将重写所继承的具有相同签名的虚方法。虚方法声明用于引入新方法,而重写方法声明则用于使现有的继承虚方法专用化(通过提供该方法的新实现)。
抽象
(abstract)
方法是没有实现的虚方法。抽象方法使用
abstract
修饰符进行声明
,
并且只有在同样被声明为
abstract
的类中才允许出现。抽象方法必须在每个非抽象派生类中重写。
下面的示例声明一个抽象类
Expression
,
它表示一个表达式树节点
;
它有三个派生类
Constant
、
VariableReference
和
Operation
,
它们分别实现了常量、变量引用和算术运算的表达式树节点。
using System;
using System.Collections;
public abstract class Expression
{
public abstract double Evaluate(Hashtable vars);
}
public class Constant: Expression
{
double value;
public Constant(double value) {
this.value = value;
}
public override double Evaluate(Hashtable vars) {
return value;
}
}
public class VariableReference: Expression
{
string name;
public VariableReference(string name) {
this.name = name;
}
public override double Evaluate(Hashtable vars) {
object value = vars[name];
if (value == null) {
throw new Exception("Unknown variable: " + name);
}
return Convert.ToDouble(value);
}
}
public class Operation: Expression
{
Expression left;
char op;
Expression right;
public Operation(Expression left, char op, Expression right) {
this.left = left;
this.op = op;
this.right = right;
}
public override double Evaluate(Hashtable vars) {
double x = left.Evaluate(vars);
double y = right.Evaluate(vars);
switch (op) {
case '+': return x + y;
case '-': return x - y;
case '*': return x * y;
case '/': return x / y;
}
throw new Exception("Unknown operator");
}
}
上面的四个类可用于为算术表达式建模。例如,使用这些类的实例,表达式
x
+
3
可如下表示。
Expression e = new Operation(
new VariableReference("x"),
'+',
new Constant(3));
Expression
实例的
Evaluate
方法将被调用
,
以计算给定的表达式的值
,
从而产生一个
double
值。该方法接受一个包含变量名称(作为哈希表项的键)和值(作为项的值)的
Hashtable
作为参数。
Evaluate
方法是一个虚抽象方法,意味着非抽象派生类必须重写该方法以提供具体的实现。
Constant
的
Evaluate
实现只是返回所存储的常量。
VariableReference
的实现在哈希表中查找变量名称
,
并返回产生的值。
Operation
的实现先对左操作数和右操作数求值
(
通过递归调用它们的
Evaluate
方法
),
然后执行给定的算术运算。
下面的程序使用
Expression
类
,
对于不同的
x
和
y
值
,
计算表达式
x
*
(y
+
2)
的值。
using System;
using System.Collections;
class Test
{
static void
Main
() {
Expression e = new Operation(
new VariableReference("x"),
'*',
new Operation(
new VariableReference("y"),
'+',
new Constant(2)
)
);
Hashtable vars = new Hashtable();
vars["x"] = 3;
vars["y"] = 5;
Console.WriteLine(e.Evaluate(vars)); // Outputs "21"
vars["x"] = 1.5;
vars["y"] = 9;
Console.WriteLine(e.Evaluate(vars)); // Outputs "16.5"
}
}
方法重载
(overloading)
允许同一类中的多个方法具有相同名称
,
条件是这些方法具有唯一的签名。在编译一个重载方法的调用时
,
编译器使用重载决策
(overload resolution)
确定要调用的特定方法。重载决策将查找与参数最佳匹配的方法,如果没有找到任何最佳匹配的方法则报告错误信息。下面的示例演示重载决策的工作机制。
Main
方法中的每个调用的注释表明实际被调用的方法。
class Test
{
static void F() {...}
Console.WriteLine("F()");
}
static void F(object x) {
Console.WriteLine("F(object)");
}
static void F(int x) {
Console.WriteLine("F(int)");
}
static void F(double x) {
Console.WriteLine("F(double)");
}
static void F(double x, double y) {
Console.WriteLine("F(double, double)");
}
static void Main() {
F(); // Invokes F()
F(1); // Invokes F(int)
F(1.0); // Invokes F(double)
F("abc"); // Invokes F(object)
F((double)1); // Invokes F(double)
F((object)1); // Invokes F(object)
F(1, 1); // Invokes F(double, double)
}
}
正如该示例所示
,
总是通过显式地将实参强制转换为确切的形参类型
,
来选择一个特定的方法。
包含可执行代码的成员统称为类的函数成员
(function member)
。前一节描述的方法是函数成员的主要类型。本节描述
C#
支持的其他种类的函数成员:构造函数、属性、索引器、事件、运算符和析构函数。
下表演示一个名为
List
的类
,
它实现一个可增长的对象列表。该类包含了几种最常见的函数成员的示例。
public class List {
|
const int defaultCapacity = 4;
|
常量
|
object[] items; int count;
|
字段
|
public List(): List(defaultCapacity) {}
public List(int capacity) { items = new object[capacity]; }
|
构造函数
|
public int Count { get { return count; } }
public string Capacity { get { return items.Length; } set { if (value < count) value = count; if (value != items.Length) { object[] newItems = new object[value]; Array.Copy(items, 0, newItems, 0, count); items = newItems; } } }
|
属性
|
public object this[int index] { get { return items[index]; } set { items[index] = value; OnListChange(); } }
|
索引器
|
public void Add(object item) { if (count == Capacity) Capacity = count * 2; items[count] = item; count++; OnChanged(); }
protected virtual void OnChanged() { if (Changed != null) Changed(this, EventArgs.Empty); }
public override bool Equals(object other) { return Equals(this, other as List); }
static bool Equals(List a, List b) { if (a == null) return b == null; if (b == null || a.count != b.count) return false; for (int i = 0; i < a.count; i++) { if (!object.Equals(a.items[i], b.items[i])) { return false; } } return true; }
|
方法
|
public event EventHandler Changed;
|
事件
|
public static bool operator ==(List a, List b) { return Equals(a, b); }
public static bool operator !=(List a, List b) { return !Equals(a, b); }
|
运算符
|
}
|
C#
支持两种构造函数
:
实例构造函数和静态构造函数。实例构造函数
(instance constructor)
是实现初始化类实例所需操作的成员。静态构造函数
(static constructor)
是一种用于在第一次加载类本身时实现其初始化所需操作的成员。
构造函数的声明如同方法一样
,
不过它没有返回类型
,
并且它的名称与其所属的类的名称相同。如果构造函数声明包含
static
修饰符,则它声明了一个静态构造函数。否则,它声明的是一个实例构造函数。
实例构造函数可以被重载。例如
,
List
类声明了两个实例构造函数
,
一个无参数
,
另一个接受一个
int
参数。实例构造函数使用
new
运算符进行调用。下面的语句分别使用
List
类的每个构造函数分配两个
List
实例。
List list1 = new List();
List list2 = new List(10);
实例构造函数不同于其他成员
,
它是不能被继承的。一个类除了其中实际声明的实例构造函数外,没有其他的实例构造函数。如果没有为某个类提供任何实例构造函数,则将自动提供一个不带参数的空的实例构造函数。
属性
(propery)
是字段的自然扩展。属性和字段都是命名的成员
,
都具有相关的类型
,
且用于访问字段和属性的语法也相同。然而,与字段不同,属性不表示存储位置。相反,属性有访问器
(accessor)
,这些访问器指定在它们的值被读取或写入时需执行的语句。
属性的声明与字段类似
,
不同的是属性声明以位于定界符
{
和
}
之间的一个
get
访问器和
/
或一个
set
访问器结束
,
而不是以分号结束。同时具有
get
访问器和
set
访问器的属性是读写属性
(read-write property)
,
只有
get
访问器的属性是只读属性
(read-only property)
,
只有
set
访问器的属性是只写属性
(write-only property)
。
get
访问器相当于一个具有属性类型返回值的无参数方法。除了作为赋值的目标,当在表达式中引用属性时,将调用该属性的
get
访问器以计算该属性的值。
set
访问器相当于具有一个名为
value
的参数并且没有返回类型的方法。当某个属性作为赋值的目标被引用,或者作为
++
或
--
的操作数被引用时,将调用
set
访问器,并传入提供新值的实参。
List
类声明了两个属性
Count
和
Capacity
,
它们分别是只读属性和读写属性。下面是这些属性的使用示例。
List names = new List();
names.Capacity = 100; // Invokes set accessor
int i = names.Count; // Invokes get accessor
int j = names.Capacity; // Invokes get accessor
与字段和方法相似
,
C#
同时支持实例属性和静态属性。静态属性使用
static
修饰符声明,而实例属性的声明不带该修饰符。
属性的访问器可以是虚的。当属性声明包括
virtual
、
abstract
或
override
修饰符时
,
修饰符应用于该属性的访问器。
索引器
(indexer)
是这样一个成员
:
它使对象能够用与数组相同的方式进行索引。索引器的声明与属性类似,不同的是该成员的名称是
this
,后跟一个位于定界符
[
和
]
之间的参数列表。在索引器的访问器中可以使用这些参数。与属性类似,索引器可以是读写、只读和只写的,并且索引器的访问器可以是虚的。
该
List
类声明了单个读写索引器
,
该索引器接受一个
int
参数。该索引器使得通过
int
值对
List
实例进行索引成为可能。例如
List numbers = new List();
names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
for (int i = 0; i < names.Count; i++) {
string s = (string)names[i];
names[i] = s.ToUpper();
}
索引器可以被重载
,
这意味着一个类可以声明多个索引器
,
只要它们的参数的数量和类型不同即可。
事件
(event)
是一种使类或对象能够提供通知的成员。事件的声明与字段类似,不同的是事件的声明包含
event
关键字,并且类型必须是委托类型。
在声明事件成员的类中
,
事件的行为就像委托类型的字段
(
前提是该事件不是抽象的并且未声明访问器
)
。该字段存储对一个委托的引用,该委托表示已添加到该事件的事件处理程序。如果尚未添加事件处理程序,则该字段为
null
。
List
类声明了一个名为
Changed
的事件成员
,
它指示有一个新的项已被添加到列表中。
Changed
事件由
OnChanged
虚方法引发
,
后者先检查该事件是否为
null
(
表明没有处理程序
)
。
“
引发一个事件
”
与
“
调用一个由该事件表示的委托
”
完全等效
,
因此没有用于引发事件的特殊语言构造。
客户端通过事件处理程序
(event handler)
来响应事件。事件处理程序使用
+=
运算符添加
,
使用
-=
运算符移除。下面的示例向
List
类的
Changed
事件添加一个事件处理程序。
using System;
class Test
{
static int changeCount;
static void ListChanged(object sender, EventArgs e) {
changeCount++;
}
static void
Main
() {
List names = new List();
names.Changed += new EventHandler(ListChanged);
names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
Console.WriteLine(changeCount); // Outputs "3"
}
}
对于要求控制事件的底层存储的高级情形
,
事件声明可以显式提供
add
和
remove
访问器
,
它们在某种程度上类似于属性的
set
访问器。
运算符
(operator)
是一种类成员
,
它定义了可应用于类实例的特定表达式运算符的含义。可以定义三种运算符:一元运算符、二元运算符和转换运算符。所有运算符都必须声明为
public
和
static
。
List
类声明了两个运算符
operator
==
和
operator
!=
,
从而为将那些运算符应用于
List
实例的表达式赋予了新的含义。具体而言,上述运算符将两个
List
实例的相等关系定义为逐一比较其中所包含的对象(使用所包含对象的
Equals
方法)。下面的示例使用
==
运算符比较两个
List
实例。
using System;
class Test
{
static void Main() {
List a = new List();
a.Add(1);
a.Add(2);
List b = new List();
b.Add(1);
b.Add(2);
Console.WriteLine(a == b); // Outputs "True"
b.Add(3);
Console.WriteLine(a == b); // Outputs "False"
}
}
第一个
Console.WriteLine
输出
True
,
原因是两个列表包含的对象数目和值均相同
。如果
List
未定义
operator
==
,
则第一个
Console.WriteLine
将输出
False
,
原因是
a
和
b
引用的是不同的
List
实例。
析构函数
(destructor)
是一种用于实现销毁类实例所需操作的成员。析构函数不能带参数,不能具有可访问性修饰符,也不能被显式调用。垃圾回收期间会自动调用所涉及实例的析构函数。
垃圾回收器在决定何时回收对象和运行析构函数方面允许有广泛的自由度。具体而言,析构函数调用的时机并不是确定的,析构函数可能在任何线程上执行。由于这些以及其他原因,仅当没有其他可行的解决方案时,才应在类中实现析构函数。
像类一样
,
结构
(struct)
是能够包含数据成员和函数成员的数据结构
,
但是与类不同
,
结构是值类型
,
不需要堆分配。结构类型的变量直接存储该结构的数据,而类类型的变量则存储对动态分配的对象的引用。结构类型不支持用户指定的继承,并且所有结构类型都隐式地从类型
object
继承。
结构对于具有值语义的小型的数据结构特别有用。复数、坐标系中的点或字典中的“键-值”对都是结构的典型示例。对小型数据结构而言,使用结构而不使用类会大大节省应用程序分配的内存量。例如,下面的程序创建并初始化一个含有
100
个点的数组。对于作为类实现的
Point
,出现了
101
个实例对象,其中,数组需要一个,它的
100
个元素每个都需要一个。
class Point
{
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
class Test
{
static void
Main
() {
Point[] points = new Point[100];
for (int i = 0; i < 100; i++) points[i] = new Point(i, i);
}
}
一种替代办法是将
Point
定义为结构。
struct Point
{
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
现在
,
只有一个对象被实例化
(
即用于数组的那个对象
),
而
Point
实例以值的形式直接内联存储在数组中。
结构构造函数也是使用
new
运算符调用
,
但是这并不意味着会分配内存。与动态分配对象并返回对它的引用不同,结构构造函数直接返回结构值本身(通常是堆栈上的一个临时位置),然后根据需要复制该结构值。
对于类
,
两个变量可能引用同一对象
,
因此对一个变量进行的操作可能影响另一个变量所引用的对象。对于结构,每个变量都有自己的数据副本,对一个变量的操作不可能影响另一个变量。例如,下面的代码段产生的输出取决于
Point
是类还是结构。
Point a = new Point(10, 10);
Point b = a;
a.x = 20;
Console.WriteLine(b.x);
如果
Point
是类
,
输出将是
20
,
因为
a
和
b
引用同一对象。如果
Point
是结构,输出将是
10
,因为
a
对
b
的赋值创建了该值的一个副本,因此接下来对
a.x
的赋值不会影响
b
这一副本。
前一示例突出了结构的两个限制。首先
,
复制整个结构通常不如复制对象引用的效率高
,
因此结构的赋值和值参数传递可能比引用类型的开销更大。其次,除了
ref
和
out
参数,不可能创建对结构的引用,这样限制了结构的应用范围。
数组
(array)
是一种包含若干变量的数据结构
,
这些变量都可以通过计算索引进行访问。数组中包含的变量(又称数组的元素
(element)
)具有相同的类型,该类型称为数组的元素类型。
数组类型为引用类型
,
因此数组变量的声明只是为数组实例的引用留出空间。实际的数组实例在运行时使用
new
运算符动态创建。
new
运算符指定新数组实例的长度
(length)
,它在该实例的生存期内是固定不变的。数组元素的索引范围从
0
到
Length
-
1
。
new
运算符自动将数组的元素初始化为它们的默认值,例如将所有数值类型初始化为零,将所有引用类型初始化为
null
。
下面的示例创建一个
int
元素的数组
,
初始化该数组
,
并打印该数组的内容。
using System;
class Test
{
static void
Main
() {
int[] a = new int[10];
for (int i = 0; i < a.Length; i++) a[i] = i * i;
for (int i = 0; i < a.Length; i++) {
Console.WriteLine("a[{0}] = {1}", i, a[i]);
}
}
}
此示例创建并操作一个一维数组
(single-dimensional array)
。
C#
还支持多维数组
(multi-dimensional array)
。数组类型的维数也称为数组类型的秩
(rank)
,它是数组类型的方括号之间逗号个数加上
1
。下面的示例分别分配一个一维数组、一个二维数组和一个三维数组。
int[] a1 = new int[10];
int[,] a2 = new int[10, 5];
int[,,] a3 = new int[10, 5, 2];
a1
数组包含
10
个元素
,
a2
数组包含
50 (10 × 5)
个元素
,
a3
数组包含
100 (10 × 5 × 2)
个元素。
数组的元素类型可以是任意类型
,
包括数组类型。对于数组元素的类型为数组的情况,我们有时称之为交错数组
(jagged array)
,原因是元素数组的长度不必全都相同。下面的示例分配一个由
int
数组组成的数组:
int[][] a = new int[3][];
a[0] = new int[10];
a[1] = new int[5];
a[2] = new int[20];
第一行创建一个具有三个元素的数组
,
每个元素的类型为
int[]
并具有初始值
null
。接下来的代码行使用对不同长度的数组实例的引用分别初始化这三个元素。
new
运算符允许使用数组初始值设定项
(array initializer)
指定数组元素的初始值
,
数组初始值设定项是在一个位于定界符
{
和
}
之间的表达式列表。下面的示例分配并初始化具有三个元素的
int[]
。
int[] a = new int[] {1, 2, 3};
注意数组的长度是从
{
和
}
之间的表达式个数推断出来的。对于局部变量和字段声明,可以进一步简写,从而不必再次声明数组类型。
int[] a = {1, 2, 3};
前面的两个示例都等效于下面的示例
:
int[] a = new int[3];
a[0] = 1;
a[1] = 2;
a[2] = 3;
接口
(interface)
定义了一个可由类和结构实现的协定。接口可以包含方法、属性、事件和索引器。接口不提供它所定义的成员的实现
—
它仅指定实现该接口的类或结构必须提供的成员。
接口可支持多重继承
(multiple inheritance)
。在下面的示例中
,
接口
IComboBox
同时从
ITextBox
和
IListBox
继承。
interface IControl
{
void Paint();
}
interface ITextBox: IControl
{
void SetText(string text);
}
interface IListBox: IControl
{
void SetItems(string[] items);
}
interface IComboBox: ITextBox, IListBox {}
类和结构可以实现多个接口。在下面的示例中
,
类
EditBox
同时实现
IControl
和
IDataBound
。
interface IDataBound
{
void Bind(Binder b);
}
public class EditBox: IControl, IDataBound
{
public void Paint() {...}
public void Bind(Binder b) {...}
}
当类或结构实现某个特定接口时
,
该类或结构的实例可以隐式地转换为该接口类型。例如
EditBox editBox = new EditBox();
IControl control = editBox;
IDataBound dataBound = editBox;
在无法静态知道某个实例是否实现某个特定接口的情况下
,
可以使用动态类型强制转换。例如,下面的语句使用动态类型强制转换获得对象的
IControl
和
IDataBound
接口实现。由于该对象的实际类型为
EditBox
,此强制转换成功。
object obj = new EditBox();
IControl control = (IControl)obj;
IDataBound dataBound = (IDataBound)obj;
在前面的
EditBox
类中
,
来自
IControl
接口的
Paint
方法和来自
IDataBound
接口的
Bind
方法使用
public
成员来实现。
C#
还支持显式接口成员实现
(explicit interface member implementation)
,
类或结构可以使用它来避免将成员声明为
public
。显式接口成员实现使用完全限定的接口成员名。例如
,
EditBox
类可以使用显式接口成员实现来实现
IControl.Paint
和
IDataBound.Bind
方法
,
如下所示。
public class EditBox: IControl, IDataBound
{
void IControl.Paint() {...}
void IDataBound.Bind(Binder b) {...}
}
显式接口成员只能通过接口类型来访问。例如
,
要调用上面
EditBox
类提供的
IControl.Paint
实现
,
必须首先将
EditBox
引用转换为
IControl
接口类型。
EditBox editBox = new EditBox();
editBox.Paint(); // Error, no such method
IControl control = editBox;
control.Paint(); // Ok
枚举类型
(enum type)
是具有一组命名常量的独特的值类型。下面的示例声明并使用一个名为
Color
的枚举类型
,
该枚举具有三个常数值
Red
、
Green
和
Blue
。
using System;
enum Color
{
Red,
Green,
Blue
}
class Test
{
static void PrintColor(Color color) {
switch (color) {
case Color.Red:
Console.WriteLine("Red");
break;
case Color.Green:
Console.WriteLine("Green");
break;
case Color.Blue:
Console.WriteLine("Blue");
break;
default:
Console.WriteLine("Unknown color");
break;
}
}
static void
Main
() {
Color c = Color.Red;
PrintColor(c);
PrintColor(Color.Blue);
}
}
每个枚举类型都有一个相应的整型类型
,
称为该枚举类型的基础类型
(underlying type)
。没有显式声明基础类型的枚举类型所对应的基础类型是
int
。枚举类型的存储格式和取值范围由其基础类型确定。一个枚举类型的值域不受它的枚举成员限制。具体而言,一个枚举的基础类型的任何一个值都可以被强制转换为该枚举类型,成为该枚举类型的一个独特的有效值。
下面的示例声明一个基础类型为
sbyte
的名为
Alignment
的枚举类型。
enum Alignment: sbyte
{
Left = -1,
Center = 0,
Right = 1
}
如前面的示例所示
,
枚举成员的声明中包含常量表达式
,
用于指定该成员的值。每个枚举成员的常数值必须在该枚举的基础类型的范围之内。如果枚举成员声明未显式指定一个值,该成员将被赋予值零(如果它是该枚举类型中的第一个值)或前一个枚举成员(按照文本顺序)的值加
1
。
可以使用类型强制转换将枚举值转换为整型值
,
反之亦然。例如
int i = (int)Color.Blue; // int i = 2;
Color c = (Color)2; // Color c = Color.Blue;
任何枚举类型的默认值都是转换为该枚举类型的整型值零。在变量被自动初始化为默认值的情况下,该默认值就是赋予枚举类型的变量的值。为了容易地获得枚举类型的默认值,文本
0
隐式地转换为任何枚举类型。因此,下面的语句是允许的。
Color c = 0;
委托类型
(delegate type)
表示对具有特定参数列表和返回类型的方法的引用。通过委托,我们能够将方法作为实体赋值给变量和作为参数传递。委托类似于在其他某些语言中的函数指针的概念,但是与函数指针不同,委托是面向对象的,并且是类型安全的。
下面的示例声明并使用一个名为
Function
的委托类型。
using System;
delegate double Function(double x);
class Multiplier
{
double factor;
public Multiplier(double factor) {
this.factor = factor;
}
public double Multiply(double x) {
return x * factor;
}
}
class Test
{
static double Square(double x) {
return x * x;
}
static double[] Apply(double[] a, Function f) {
double[] result = new double[a.Length];
for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
return result;
}
static void
Main
() {
double[] a = {0.0, 0.5, 1.0};
double[] squares = Apply(a, new Function(Square));
double[] sines = Apply(a, new Function(Math.Sin));
Multiplier m = new Multiplier(2.0);
double[] doubles = Apply(a, new Function(m.Multiply));
}
}
Function
委托类型的实例可以引用任何接受
double
参数并返回
double
值的方法。
Apply
方法将给定的
Function
作用于
double[]
的元素
,
并返回含有结果的
double[]
。在
Main
方法中
,
Apply
用于将三个不同的函数应用于一个
double[]
。
委托可以既可以引用静态方法
(
例如前一示例中的
Square
或
Math.Sin
),
也可以引用实例方法
(
例如前一示例中的
m.Multiply
)
。引用了实例方法的委托也就引用了一个特定的对象,当通过该委托调用这个实例方法时,该对象在调用中成为
this
。
委托的一个有趣且有用的属性在于
,
它不知道也不关心它所引用的方法的类
;
它所关心的仅是所引用的方法与委托具有相同的参数和返回类型。
C#
程序中的类型、成员和其他实体支持修饰符
,
这些修饰符控制它们的行为的某些方面。例如
,
方法的可访问性使用
public
、
protected
、
internal
和
private
修饰符控制。
C#
使此功能一般化
,
以便能够将用户定义类型的声明信息附加到程序实体
,
并在运行时检索。这种附加的声明信息是程序通过定义和使用属性
(attribute)
来指定的。
下面的示例声明一个
HelpAttribute
属性
,
该属性可放置在程序实体上
,
以便提供指向其关联文档的链接。
using System;
public class HelpAttribute: Attribute
{
string url;
string topic;
public HelpAttribute(string url) {
this.url = url;
}
public string Url {
get { return url; }
}
public string Topic {
get { return topic; }
set { topic = value; }
}
}
所有属性类都从
.NET Framework
提供的
System.Attribute
基类派生而来。如果属性的名称以
Attribute
结尾
,
在引用该属性时可以省略此名称后缀。例如
,
HelpAttribute
属性可以按如下方式使用。
[Help("http://msdn.microsoft.com/.../MyClass.htm")]
public class Widget
{
[Help("http://msdn.microsoft.com/.../MyClass.htm", Topic = "Display")]
public void Display(string text) {}
}
此示例将一个
HelpAttribute
附加到
Widget
类
,
并且将另一个
HelpAttribute
附加到该类中的
Display
方法。属性类的公共构造函数控制在将属性附加到程序实体时所必须提供的信息。可以通过引用属性
(attribute)
类的公共读写属性
(property)
提供附加信息
(
例如前面对
Topic
属性的引用
)
。
下面的示例演示如何使用反射在运行时检索给定程序实体的属性信息。
using System;
using System.Reflection;
class Test
{
static void ShowHelp(MemberInfo member) {
HelpAttribute a = Attribute.GetCustomAttribute(member,
typeof(HelpAttribute)) as HelpAttribute;
if (a == null) {
Console.WriteLine("No help for {0}", member);
}
else {
Console.WriteLine("Help for {0}:", member);
Console.WriteLine(" Url={0}, Topic={1}", a.Url, a.Topic);
}
}
static void
Main
() {
ShowHelp(typeof(Widget));
ShowHelp(typeof(Widget).GetMethod("Display"));
}
}
当通过反射请求特定属性时
,
将使用程序源中提供的信息调用属性类的构造函数
,
并返回生成的属性实例。如果通过属性
(property)
提供了附加信息
,
那些属性
(property)
将在返回属性
(attribute)
实例之前被设置为给定的值。