关键字
using:用于在程序中包含命令空间。一个程序可以包含多个 using 语句。
class:用于声明一个类。
关键字是C#编译器预定义的保留字。这些关键字不能用作标识符,如使用需在前面加@。
保留关键字 | ||||||
abstract | as | base | bool | break | byte | case |
catch | char | checked | class | const | continue | decimal |
default | delegate | do | double | else | enum | event |
explicit | extern | false | finally | fixed | float | for |
foreach | goto | if | implicit | in | in (generic modifier) | int |
interface | internal | is | lock | long | namespace | new |
null | object | operator | out | out (generic modifier) | override | params |
private | protected | public | readonly | ref | return | sbyte |
sealed | short | sizeof | stackalloc | static | string | struct |
switch | this | throw | true | try | typeof | uint |
ulong | unchecked | unsafe | ushort | using | virtual | void |
volatile | while | |||||
上下文关键字 | ||||||
add | alias | ascending | descending | dynamic | from | get |
global | group | into | join | let | orderby | partial (type) |
partial (method) | remove | select | set |
注释
注释是用于解释代码。编译器会忽略注释的条目。
/**/:多行注释,以 /* 开始,以 */ 结束。
//:单行注释。不会被编译。
///:会被编译(会减慢编译速度,但不影响执行速度)。
作用:1、这些注释能够生成一个XML文件;2、以这种方式类、属性、方法进行注释后,挡在其它页面使用时,黄色提示框内会把写的注释内容会被显示出来,
变量
变量是类的属性或数据成员,用于存储数据。
标识符
标识符是用来识别类、变量、函数或任何其他用户自定义的项目。
1、标识符必须以字母、下划线或@开头,后面可以跟一系列的字母、数字(0-9)、下划线(_)、@。
2、标识符的第一个字不能是数字。
3、标识符必须不包含任何嵌入的空格或符号,比如?-+!#%^&*()[]/\.
4、标识符不能是C#关键字。除非它们有一个@前缀。
5、标识符必须区分大小写。大写字母与小写字母被认为是不同的字母。
6、不能与C#的类库名称相同。
C#中类的实例化
通过已有的类(class)创建出该类的一个对象(object),这一过程叫做类的实例化。
数据类型
值类型(Value types)
引用类型(Referrnce types)
指针类型(Pointer types)
值类型(Value types)
值类型变量可以直接分配给一个值。它们是从System.ValueType中派生的。
以下列出了C#2010中可用的值类型:
类型 | 描述 | 范围 | 默认值 |
bool | 布尔值 | True 或 False | False |
byte | 8 位无符号整数 | 0 到 255 | 0 |
char | 16 位 Unicode 字符 | U +0000 到 U +ffff | '\0' |
decimal | 128 位精确的十进制值,28-29 有效位数 | (-7.9 x 1028 到 7.9 x 1028) / 100 到 28 | 0.0M |
double | 64 位双精度浮点型 | (+/-)5.0 x 10-324 到 (+/-)1.7 x 10308 | 0.0D |
float | 32 位单精度浮点型 | -3.4 x 1038 到 + 3.4 x 1038 | 0.0F |
int | 32 位有符号整数类型 | -2,147,483,648 到 2,147,483,647 | 0 |
long | 64 位有符号整数类型 | -923,372,036,854,775,808 到 9,223,372,036,854,775,807 | 0L |
sbyte | 8 位有符号整数类型 | -128 到 127 | 0 |
short | 16 位有符号整数类型 | -32,768 到 32,767 | 0 |
uint | 32 位无符号整数类型 | 0 到 4,294,967,295 | 0 |
ulong | 64 位无符号整数类型 | 0 到 18,446,744,073,709,551,615 | 0 |
ushort | 16 位无符号整数类型 | 0 到 65,535 | 0 |
sizeof方法可得到特定平台上一个类型或变量的准确尺寸,如sizeof(int)
引用类型(Reference types)
引用类型不包含存储在变量中的实际数据,但它们包含对变量的引用。
内置的引用类型有:object、dynamic和string。
对象(object)类型
对象(object)类型是C#通用类型系统(Common Type System-CTS)中所有数据类型的终极基类。对象(object)类型可以被分配任何其他类型(值类型、引用类型、预定义类型或用户自定义类型)的值。但是,再分配值之前,需要先进行类型转换。
当一个值类型转换为对象类型时,称为装箱;当一个对象类型转换为值类型时,称为拆箱。
动态(Dynamic)类型
动态类型与对象类型相似,但是对象变量的类型检查是在编译时发生的,而动态类型变量的类型检查是在运行时发生的。
字符串(String)类型
字符串(String)类型是从对象(object)类型派生的。字符串(String)类型的值可以通过两种形式进行分配:引号和@引号。
指针类型(Pointer types)
指针类型变量存储另一种类型的内存地址。
C#中String与string的区别
string是C#中的类,String是.net Framework的类(在C#IDE中不会显示蓝色)
string不能作为类、结构、枚举、字段、变量、方法、属性的名字,String可以。
string是C#中的关键字,String是CLR的类型名字(也算是关键字)
string在编译时C#编译器会默认将其转换为String
string是绿色,String是蓝色
值类型的特点
不能从值类型派生新类型,但可以结构实现接口;
值类型不能包含null值;
每个值类型都具有一个初始化该类型的隐式默认构造函数。
C#类型转换
类型转化从根本上说是类型铸造,或者说是吧数据从一中类型转换为另一种类型。
隐式类型转换--C#默认的安全转换,不会导致数据丢失。
显示类型转换强制类型转换,会造成数据丢失。
序号 | 方法 & 描述 |
1 | ToBoolean 如果可能的话,把类型转换为布尔型。 |
2 | ToByte 把类型转换为字节类型。 |
3 | ToChar 如果可能的话,把类型转换为单个 Unicode 字符类型。 |
4 | ToDateTime 把类型(整数或字符串类型)转换为 日期-时间 结构。 |
5 | ToDecimal 把浮点型或整数类型转换为十进制类型。 |
6 | ToDouble 把类型转换为双精度浮点型。 |
7 | ToInt16 把类型转换为 16 位整数类型。 |
8 | ToInt32 把类型转换为 32 位整数类型。 |
9 | ToInt64 把类型转换为 64 位整数类型。 |
10 | ToSbyte 把类型转换为有符号字节类型。 |
11 | ToSingle 把类型转换为小浮点数类型。 |
12 | ToString 把类型转换为字符串类型。 |
13 | ToType 把类型转换为指定类型。 |
14 | ToUInt16 把类型转换为 16 位无符号整数类型。 |
15 | ToUInt32 把类型转换为 32 位无符号整数类型。 |
16 | ToUInt64 把类型转换为 64 位无符号整数类型。 |
C#变量
供程序操作的存储区的名字。
类型 | 举例 |
整数类型 | sbyte、byte、short、ushort、int、uint、long、ulong 和 char |
浮点型 | float 和 double |
十进制类型 | decimal |
布尔类型 | true 或 false 值,指定的值 |
空类型 | 可为空值的数据类型 |
C#中的Lvalues和Rvalues
1、lvalue:表达式可以出现在赋值语句的左边或右边。
2、rvalue:表达式可以出现在赋值语句的右边,不能出现在赋值语句的左边。
常量
常量是固定值,程序执行期间不会改变。常量可以是任何基本数据的类型浮点常量、字符常量或字符串常量,还有枚举常量。
常量可以被当做常规的变量,只是它们的值在定义后不能被修改。
整数常量
整数常量可以是十进制、八进制或十六进制的常量。
Convert.ToInt32()与int.Parse()的区别
1、Convert.ToInt32(null)会返回0不会产生任何异常,但int.Parse()则会产生异常。
2、对数据进行四舍五入时的区别
3、int.Parse是转换String为int,Convert.ToInt32是转换继承自Object的对象为int
C#运算符
算术运算符
关系运算符
逻辑运算符
位运算符
赋值运算符
其他运算符
算术运算符
下表显示了C#支持的所有算术运算符。假设变量A的值为10,变量B的值为20,则:
运算符 | 描述 | 实例 |
+ | 把两个操作数相加 | A + B 将得到 30 |
- | 从第一个操作数中减去第二个操作数 | A - B 将得到 -10 |
* | 把两个操作数相乘 | A * B 将得到 200 |
/ | 分子除以分母 | B / A 将得到 2 |
% | 取模运算符,整除后的余数 | B % A 将得到 0 |
++ | 自增运算符,整数值增加 1 | A++ 将得到 11 |
-- | 自减运算符,整数值减少 1 | A-- 将得到 9 |
关系运算符
下表显示了C#支持的所有关系运算符。假设变量A的值为10,变量B的值为20,则:
运算符 | 描述 | 实例 |
== | 检查两个操作数的值是否相等,如果相等则条件为真。 | (A == B) 不为真。 |
!= | 检查两个操作数的值是否相等,如果不相等则条件为真。 | (A != B) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 | (A > B) 不为真。 |
< | 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 | (A < B) 为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 | (A >= B) 不为真。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 | (A <= B) 为真。 |
逻辑运算符
下表显示了C#支持的所有逻辑运算符。假设变量A为布尔值true,变量B为布尔值false:
运算符 | 描述 | 实例 |
&& | 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 | (A && B) 为假。 |
|| | 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 | (A || B) 为真。 |
! | 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 | !(A && B) 为真。 |
位运算符
位运算符作用于位,并逐位执行操作。&、|和^的真值表如下所示:
p | q | p & q | p | q | p ^ q |
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 1 | 1 |
下表列出了C#支持的位运算符。假设变量A的值为60,变量B的值为13,则:
运算符 | 描述 | 实例 |
& | 如果同时存在于两个操作数中,二进制 AND 运算符复制一位到结果中。 | (A & B) 将得到 12,即为 0000 1100 |
| | 如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中。 | (A | B) 将得到 61,即为 0011 1101 |
^ | 如果存在于其中一个操作数中但不同时存在于两个操作数中,二进制异或运算符复制一位到结果中。 | (A ^ B) 将得到 49,即为 0011 0001 |
~ | 按位取反运算符是一元运算符,具有"翻转"位效果,即0变成1,1变成0,包括符号位。 | (~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码形式。 |
<< | 二进制左移运算符。左操作数的值向左移动右操作数指定的位数。 | A << 2 将得到 240,即为 1111 0000 |
>> | 二进制右移运算符。左操作数的值向右移动右操作数指定的位数。 | A >> 2 将得到 15,即为 0000 1111 |
赋值运算符
下表列出了C#支持的赋值运算符:
运算符 | 描述 | 实例 |
= | 简单的赋值运算符,把右边操作数的值赋给左边操作数 | C = A + B 将把 A + B 的值赋给 C |
+= | 加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数 | C += A 相当于 C = C + A |
-= | 减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数 | C -= A 相当于 C = C - A |
*= | 乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数 | C *= A 相当于 C = C * A |
/= | 除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数 | C /= A 相当于 C = C / A |
%= | 求模且赋值运算符,求两个操作数的模赋值给左边操作数 | C %= A 相当于 C = C % A |
<<= | 左移且赋值运算符 | C <<= 2 等同于 C = C << 2 |
>>= | 右移且赋值运算符 | C >>= 2 等同于 C = C >> 2 |
&= | 按位与且赋值运算符 | C &= 2 等同于 C = C & 2 |
^= | 按位异或且赋值运算符 | C ^= 2 等同于 C = C ^ 2 |
|= | 按位或且赋值运算符 | C |= 2 等同于 C = C | 2 |
其他运算符
下表列出了C#支持的其它一些重要的运算符,包括sizeof、typeof和?:。
运算符 | 描述 | 实例 |
sizeof() | 返回数据类型的大小。 | sizeof(int),将返回 4. |
typeof() | 返回 class 的类型。 | typeof(StreamReader); |
& | 返回变量的地址。 | &a; 将得到变量的实际地址。 |
* | 变量的指针。 | *a; 将指向一个变量。 |
? : | 条件表达式 | 如果条件为真 ? 则为 X : 否则为 Y |
is | 判断对象是否为某一类型。 | If( Ford is Car) // 检查 Ford 是否是 Car 类的一个对象。 |
as | 强制转换,即使转换失败也不会抛出异常。 | Object obj = new StringReader("Hello"); StringReader r = obj as StringReader; |
C#中的运算符优先级
类别 | 运算符 | 结合性 |
后缀 | () [] -> . ++ - - | 从左到右 |
一元 | + - ! ~ ++ - - (type)* & sizeof | 从右到左 |
乘除 | * / % | 从左到右 |
加减 | + - | 从左到右 |
移位 | << >> | 从左到右 |
关系 | < <= > >= | 从左到右 |
相等 | == != | 从左到右 |
位与 AND | & | 从左到右 |
位异或 XOR | ^ | 从左到右 |
位或 OR | | | 从左到右 |
逻辑与 AND | && | 从左到右 |
逻辑或 OR | || | 从左到右 |
条件 | ?: | 从右到左 |
赋值 | = += -= *= /= %=>>= <<= &= ^= |= | 从右到左 |
逗号 | , | 从左到右 |
判断
语句 | 描述 |
一个 if 语句 由一个布尔表达式后跟一个或多个语句组成。 | |
一个 if 语句 后可跟一个可选的 else 语句,else 语句在布尔表达式为假时执行。 | |
您可以在一个 if 或 else if 语句内使用另一个 if 或 else if 语句。 | |
一个 switch 语句允许测试一个变量等于多个值时的情况。 | |
您可以在一个 switch 语句内使用另一个 switch 语句。 |
?:运算符
Exp1?Exp2:Exp3;
循环类型
循环类型 | 描述 |
当给定条件为真时,重复语句或语句组。它会在执行循环主体之前测试条件。 | |
多次执行一个语句序列,简化管理循环变量的代码。 | |
除了它是在循环主体结尾测试条件外,其他与 while 语句类似。 | |
您可以在 while、for 或 do..while 循环内使用一个或多个循环。 |
循环控制语句
控制语句 | 描述 |
终止 loop 或 switch 语句,程序流将继续执行紧接着 loop 或 switch 的下一条语句。 | |
引起循环跳过主体的剩余部分,立即重新开始测试条件。 |
无限循环
条件永不为假,则循环变成无限循环
for (; ; ) { Console.WriteLine("Hey! I am Trapped"); }
封装
封装被定义为”把一个或多个项目封闭在一个物理的或者逻辑的包中“。在面向对象程序设计方法论中,封装是为了防止对现实细节的访问。
抽象和封装是面向对象程序设计的相关特性。抽象允许相关信息可视化,封装则使开发者实现所需级别的抽象。
C#封装根据具体你的需要,设置使用者的访问权限,并通过访问修饰符来实现。
访问修饰符定义了类成员的范围和可见性。
public:所有对象都可以访问;
private:对象本身在对象内部可以访问;
protected:只有该类对象及其子类对象可以访问;
internal:同一个程序集的对象可以访问;
protected internal:访问限于当前程序集或派生自包含类的类型。
方法
方法是把一些相关的语句组织在一起,用来执行一个任务的语句块。
使用一个方法需要:定义方法;调用方法。
<Access Specifier> <Return Type> <Method Name>(Parameter List) { Method Body }
下面是方法的各个元素:
- Access Specifier:访问修饰符,这个决定了变量或方法对于另一个类的可见性。
- Return type:返回类型,一个方法可以返回一个值。返回类型是方法返回的值的数据类型。如果方法不返回任何值,则返回类型为 void。
- Method name:方法名称,是一个唯一的标识符,且是大小写敏感的。它不能与类中声明的其他标识符相同。
- Parameter list:参数列表,使用圆括号括起来,该参数是用来传递和接收方法的数据。参数列表是指方法的参数类型、顺序和数量。参数是可选的,也就是说,一个方法可能不包含参数。
- Method body:方法主体,包含了完成任务所需的指令集。
参数传递
三种向方法传递参数的方式
方式 | 描述 |
值参数 | 这种方式复制参数的实际值给函数的形式参数,实参和形参使用的是两个不同内存中的值。在这种情况下,当形参的值发生改变时,不会影响实参的值,从而保证了实参数据的安全。 |
引用参数 | 这种方式复制参数的内存位置的引用给形式参数。这意味着,当形参的值发生改变时,同时也改变实参的值。 |
输出参数 | 这种方式可以返回多个值。 |
可空类型(Nullable)
单问号?:用于对int,double,bool等无法直接赋值为null的数据类型进行null的赋值,意思是这个数据类型NullAble类型的。
与双问号??:可用于判断一个变量在为null时返回一个指定的值。
数组
数组是一个存储相同类型元素的固定大小的顺序集合。数组是用来存储数据的集合,通常认为数组是一个同一类型变量的集合。
数组细节
概念 | 描述 |
C# 支持多维数组。多维数组最简单的形式是二维数组。 | |
C# 支持交错数组,即数组的数组。 | |
您可以通过指定不带索引的数组名称来给函数传递一个指向数组的指针。 | |
这通常用于传递未知数量的参数给函数。 | |
在 System 命名空间中定义,是所有数组的基类,并提供了各种用于数组的属性和方法。 |
结构体
结构体是值类型数据结构。它使得一个单一变量可以存储各种数据类型的相关数据。struct关键字用于创建结构体。结构体是用来代表一个记录。
结构有以下特点:
- 结构可带有方法、字段、索引、属性、运算符方法和事件。
- 结构可定义构造函数,但不能定义析构函数。但是,您不能为结构定义默认的构造函数。默认的构造函数是自动定义的,且不能被改变。
- 与类不同,结构不能继承其他的结构或类。
- 结构不能作为其他结构或类的基础结构。
- 结构可实现一个或多个接口。
- 结构成员不能指定为 abstract、virtual 或 protected。
- 当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
- 如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。
类VS结构
类是引用类型,结构是值类型。
结构不支持继承。
结构不能声明默认的构造函数。
枚举(Enum)
枚举是一组命名整型常量。枚举类型是使用enum关键字声明的。C#枚举是值数据类型。枚举包含自己的值,且不能继承或传承继承。
类(Class)
对象是类的实例。构成类的方法和变量称为类的成员。
类的定义是以关键字class开始,后跟类名。类的主体,包含在一对花括号内。
成员函数和封装
类的成员函数是在一个类定义中有它的定义或原型的函数,就像其他变量一样。作为类的一个成员,它能在类的任何对象上操作,且能访问该对象的类的所有成员。
成员变量是对象的属性(从设计角度),且他们保持私有来实现封装。这些变量只能使用公共成员函数来访问。
C#中的构造函数
类的构造函数是类的一个特殊的成员函数,当创建类的新对象时执行。
构造函数的名称与类的名称完全相同,它没有任何返回类型。
默认的构造函数没有任何参数。一个带有参数的构造函数可以有参数,这种构造函数叫做参数化构造函数。
C#中的析构函数
类的析构函数是类的一个特殊的成员函数,当类的对象超出范围时执行。
析构函数的名称是在类的名称前加上一个波浪形(~)作为前缀,它不返回值,也不带任何参数。
析构函数用于在结束程序(比如关闭程序,释放内存等)之前释放资源。析构函数不能继承或重载。
C#类的静态成员
继承
继承允许我们根据一个类来定义另一个类,这使得创建和维护应用程序变得更加容易,同时也有利于重用代码和节省开发空间。
当创建一个类时,程序员不需要完全重新编写的数据成员和成员函数,只需要设计一个新的类,继承了已有的类的成员即可。这个已有的类被称为基类,这个新的类被称为派生类。
基类和派生类
一个类可以派生自多个类或接口,这意味着它可以从多个基类或接口继承数据和函数。
类的初始化
派生类继承了基类的成员变量和成员方法。因此父类对象应在子类对象创建之前创建。可以在成员初始化列表中进行父类的初始化。
C#多重继承
多重继承指的是一个类别可以同时从多余一个父类继承行为与特征。于单一继承相对,单一继承指一个类别只可以继承自一个父类。
C#不支持多重继承。但可以使用接口来实现多重继承。
多态性
多态:一个接口,多个功能。
静态多态性:编译时发生的函数响应(调用该);
动态多态性:运行时发生函数响应。
静态绑定(早起绑定):编译时函数和对象的连接机制。
两种技术实现静态多态性:函数重载/运算符重载。
函数重载:在同一范围内对相同函数名有多个定义,可以是参数类型或参数个数的不同,但不许只有返回值类型不同。
运算符重载:关键字abstract声明抽象类:用于接口部分类的实现(派生类继承抽象类时,实现完成)。抽象类包含抽象方法,抽象方法可被派生类实现。
抽象类规则:
1)不能创建抽象类的实例
2)不能再抽象类外定义抽象方法
3)不能把抽象类声明为sealed(类前带关键字sealed代表该类是密封类,不能被继承)
关键字virtual声明虚方法:用于方法在继承类中的实现(在不同的继承类中有不同的实现)。
抽象类和虚方法共同实现动态多态性。
注:继承类中的重写虚函数需要声明关键字override,在方法参数传入中写(类名 形参名)例如public void CallArea(Shape sh),意思是传入一个shape类型的类。
virtual和abstract
virtual和abstract都是用来修饰父类的,通过覆盖父类的定义,让子类重新定义。
1、virtual修饰的方法必须有实现(哪怕仅仅添加一对大括号),而abstract修饰的方法不一定能实现。
2、virtual可以被子类重写,而abstract必须被子类重写。
3、如果类成员被abstract修饰,则该类前必须添加abstract,因为只有抽象类才可以有抽象方法。
4、无法创建abstract类的实例,只能被继承无法实例化。
重载和重写
重载(overload)是提供了一种机制,相同函数名通过不同的返回值类型以及参数来表示区分的机制。
重写(override)是用于重写基类的虚方法,这样在派生类中提供一个新的方法。
接口
接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同“是什么”部分,派生类定义了语法合同“怎么做”部分。
接口定义了属性、方法、事件,这些都是接口的成员。接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构。
接口使得实现接口的类或结构在形式上保持一致。
抽象类在某种程度上与接口类似,但是,它们大多数只是用在当只有少数方法由基类声明由派生类实现时。
定义接口
接口使用interface关键字声明,它与类的声明类似。
命名空间
命名空间的设计母的是提供一种让一组名称与其他名称分隔开的方式。在一个命名空间中声明的类的名称与另一个命名空间中生命的相同的类的名称不冲突。
定义命名空间
命名空间的定义是以关键字namespace开始,后跟命名空间的名称。
using关键字
using关键字表明程序使用的是给定命名空间中的名称。
嵌套命名空间
命名空间可以被嵌套,即可以在一个命名空间内定义另一个命名空间。
using的用法
1)using指令:引入命名空间
using Model;
2)using static指令:指定无序指定类型名称即可访问其静态成员的类型
using static System.Math;var = PI;
3)起别名
using Project=PC.MyCompany.Project;
4)using语句:将实例与代码绑定
using(Font font3=new Font("Arial",10.0f),
font4=new Font("Arial",10.0f))
{
//Use font3 and font4.
}
预处理器指令
预处理器指令指导编译器在实际编译开始之前对信息进行预处理。
所有的预处理器指令都是以#开始。且在一行上,只有空白字符可以出现在预处理器指令之前。预处理器指令不是语句,所以它们不以分号(;)结束。
C#编译器没有一个单独的预处理器,但是,指令被处理时就像是有一个单独的预处理器一样。在C#中预处理器指令用于在条件编译中起作用。与C和C++不同的是,它们不是用来创建宏。一个预处理器指令必须是该行上的唯一指令。
预处理器指令 | 描述 |
#define | 它用于定义一系列成为符号的字符。 |
#undef | 它用于取消定义符号。 |
#if | 它用于测试符号是否为真。 |
#else | 它用于创建复合条件指令,与 #if 一起使用。 |
#elif | 它用于创建复合条件指令。 |
#endif | 指定一个条件指令的结束。 |
#line | 它可以让您修改编译器的行数以及(可选地)输出错误和警告的文件名。 |
#error | 它允许从代码的指定位置生成一个错误。 |
#warning | 它允许从代码的指定位置生成一级警告。 |
#region | 它可以让您在使用 Visual Studio Code Editor 的大纲特性时,指定一个可展开或折叠的代码块。 |
#endregion | 它标识着 #region 块的结束。 |
#define预处理器
#define 允许定义一个符号,通过使用符号作为传递给#if指令的表达式,表达式将返回true。
正则表达式
正则表达式是一种匹配输入文本的模式。.Net框架提供了允许这种匹配的正则表达式引擎。模式由一个或多个字符、运算符合结构组成。
定义正则表达式
下面列出了用于定义正则表达式的各种类别的字符、运算符和结构。
1)字符转义
2)字符类
3)定位点
4)分组构造
5)限定符
6)反向引用构造
7)备用构造
8)替换
9)杂项构造
字符转义
正则表达式中的反斜杠字符(\)指示其后跟的字符是特殊字符,或应按原义解释该字符。
转义字符 | 描述 | 模式 | 匹配 |
\a | 与报警 (bell) 符 \u0007 匹配。 | \a | "Warning!" + '\u0007' 中的 "\u0007" |
\b | 在字符类中,与退格键 \u0008 匹配。 | [\b]{3,} | "\b\b\b\b" 中的 "\b\b\b\b" |
\t | 与制表符 \u0009 匹配。 | (\w+)\t | "Name\tAddr\t" 中的 "Name\t" 和 "Addr\t" |
\r | 与回车符 \u000D 匹配。(\r 与换行符 \n 不是等效的。) | \r\n(\w+) | "\r\Hello\nWorld." 中的 "\r\nHello" |
\v | 与垂直制表符 \u000B 匹配。 | [\v]{2,} | "\v\v\v" 中的 "\v\v\v" |
\f | 与换页符 \u000C 匹配。 | [\f]{2,} | "\f\f\f" 中的 "\f\f\f" |
\n | 与换行符 \u000A 匹配。 | \r\n(\w+) | "\r\Hello\nWorld." 中的 "\r\nHello" |
\e | 与转义符 \u001B 匹配。 | \e | "\x001B" 中的 "\x001B" |
\ nnn | 使用八进制表示形式指定一个字符(nnn 由二到三位数字组成)。 | \w\040\w | "a bc d" 中的 "a b" 和 "c d" |
\x nn | 使用十六进制表示形式指定字符(nn 恰好由两位数字组成)。 | \w\x20\w | "a bc d" 中的 "a b" 和 "c d" |
\c X \c x | 匹配 X 或 x 指定的 ASCII 控件字符,其中 X 或 x 是控件字符的字母。 | \cC | "\x0003" 中的 "\x0003" (Ctrl-C) |
\u nnnn | 使用十六进制表示形式匹配一个 Unicode 字符(由 nnnn 表示的四位数)。 | \w\u0020\w | "a bc d" 中的 "a b" 和 "c d" |
\ | 在后面带有不识别的转义字符时,与该字符匹配。 | \d+[\+-x\*]\d+\d+[\+-x\*\d+ | "(2+2) * 3*9" 中的 "2+2" 和 "3*9" |
异常处理
异常是在程序执行期间出现的问题。C#中的异常是对程序运行时出现的特殊情况的一种响应。
异常提供了一种把程序控制权从某个部分转移到另一个部分的方式。
try:一个try块标识了一个将被激活的特定的异常的代码块。后跟一个或多个catch块。
catch:程序通过异常处理程序捕获异常。catch关键字表示异常的捕获。
finally:finally块用于执行给定的语句,不管异常是否被抛出都会执行。
throw:当问题出现时,程序抛出一个异常。使用throw关键字来完成。
C#中的异常类
C#异常是使用类来表示的。C#中的异常类主要是直接或间接地派生于System.Exception类。
异常类 | 描述 |
System.IO.IOException | 处理 I/O 错误。 |
System.IndexOutOfRangeException | 处理当方法指向超出范围的数组索引时生成的错误。 |
System.ArrayTypeMismatchException | 处理当数组类型不匹配时生成的错误。 |
System.NullReferenceException | 处理当依从一个空对象时生成的错误。 |
System.DivideByZeroException | 处理当除以零时生成的错误。 |
System.InvalidCastException | 处理在类型转换期间生成的错误。 |
System.OutOfMemoryException | 处理空闲内存不足生成的错误。 |
System.StackOverflowException | 处理栈溢出生成的错误。 |
C#文件的输入与输出
一个文件是一个存储在磁盘中带有指定名称和目录路径的数据集合。当打开文件进行读写时,它变成一个流。从根本上说,流就是通过路径传递的字节序列。有两个主要的流:输入流和输出流。输入流用于从文件读入数据(写操作),输出流用于向文件写入数据(读操作)。
C#I /O类
System.IO命名空间有各种不同的类,用于执行各种文件的操作,如创建和删除文件,读取或写入文件,关闭文件等。
下表列出了一些System.IO命名空间中常用的非抽象类:
I/O 类 | 描述 |
BinaryReader | 从二进制流读取原始数据。 |
BinaryWriter | 以二进制格式写入原始数据。 |
BufferedStream | 字节流的临时存储。 |
Directory | 有助于操作目录结构。 |
DirectoryInfo | 用于对目录执行操作。 |
DriveInfo | 提供驱动器的信息。 |
File | 有助于处理文件。 |
FileInfo | 用于对文件执行操作。 |
FileStream | 用于文件中任何位置的读写。 |
MemoryStream | 用于随机访问存储在内存中的数据流。 |
Path | 对路径信息执行操作。 |
StreamReader | 用于从字节流中读取字符。 |
StreamWriter | 用于向一个流中写入字符。 |
StringReader | 用于读取字符串缓冲区。 |
StringWriter | 用于写入字符串缓冲区。 |
FileStream类
System.IO命名空间中的FileStream类有助于文件的读写与关闭。该类派生自抽象类Stream。
参数 | 描述 |
FileMode | FileMode 枚举定义了各种打开文件的方法。FileMode 枚举的成员有: Append:打开一个已有的文件,并将光标放置在文件的末尾。如果文件不存在,则创建文件。 Create:创建一个新的文件。如果文件已存在,则删除旧文件,然后创建新文件。 CreateNew:指定操作系统应创建一个新的文件。如果文件已存在,则抛出异常。 Open:打开一个已有的文件。如果文件不存在,则抛出异常。 OpenOrCreate:指定操作系统应打开一个已有的文件。如果文件不存在,则用指定的名称创建一个新的文件打开。 Truncate:打开一个已有的文件,文件一旦打开,就将被截断为零字节大小。然后我们可以向文件写入全新的数据,但是保留文件的初始创建日期。如果文件不存在,则抛出异常。 |
FileAccess | FileAccess 枚举的成员有:Read、ReadWrite 和 Write。 |
FileShare | FileShare 枚举的成员有: Inheritable:允许文件句柄可由子进程继承。Win32 不直接支持此功能。 None:谢绝共享当前文件。文件关闭前,打开该文件的任何请求(由此进程或另一进程发出的请求)都将失败。 Read:允许随后打开文件读取。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取的请求(由此进程或另一进程发出的请求)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。 ReadWrite:允许随后打开文件读取或写入。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取或写入的请求(由此进程或另一进程发出)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。 Write:允许随后打开文件写入。如果未指定此标志,则文件关闭前,任何打开该文件以进行写入的请求(由此进程或另一进过程发出的请求)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。 Delete:允许随后删除文件。 |