作者:Ricky Feng
制作时间:2005年3月30日
3.1 C#基础
{} – 语句块
// - 单行注释
/* */ - 多行注释
3.2 数据类型
1.值类型
包含一组数据,分配在堆栈上。
2.引用类型
没有预先指定大小,分配在堆上的。
3.3 C#预定义类型
3.3.1 值类型
1.整数类型
名称 CTS 类型 说明 范围
sbyte System.Sbyte 8位有符号整数 -128 到 127
short System.Int16 16… -32768 到 32767
int System.Int32 32… -2147483648 到 2147483647
long System.Int64 64… -9223372036854775808 到 9223372036854775807
byte System.Byte 8位无符号整数 0 到 255
ushort System.Uint16 16… 0 到 65535
uint System.Uint32 32… 0 到 4294967295
ulong System.Uint64 64… 0 到 18446744073709551615
2.浮点数
名称 CTS类型 说明 位数 范围
Float System.Single 32位单精度 7 +/- 1.5 x 10-45 到 +/- 3.4 x 1038
Double System.Double 64位双精度 15/16 +/- 5.0 x 10-324 到 +/- 1.7 x 10308
3.Decimal类型
名称 CTS类型 说明 位数 范围
decimal System.Decimal 128位高精度十进制数 28 +/- 1.0 x 10-28 到 +/- 7.9 x 1028
4.Boolean类型
名称 CTS类型 值 注意
Bool System.Boolean true 和 false 不能和整数相互转换
5.Character
名称 CTS类型 值 注意
Char System.Char 表示一个16位的字符 用单引号引起来表示,双引号会产生错误
6.转义序列
转义序列 字符
/’ 单引号
/” 双引号
// 反斜杠
/0 空
/a 警告
/b 退格
/f 换页
/n 换行
/r 回车
/t 水平制表符
/v 垂直制表符
3.3.2 引用类型
在C#中实例化一个引用对象需要使用new关键字。
Example: Something objSomething;
objSomething = new Something();
名称 CTS类 说明
object System.Object CTS的其它类型都是从它派生来的
string System.String Unicode 字符串;如在字符串前加上@在这个字符串的所有字符看作是其原来的含义,即不会解释转义字符
3.4 复合类型
3.4.1 值类型
1.结构 – 是一种特殊的类,是把相关数据组合在一起打包到一个变量
说明:它是值类型,如果要把一个结构的值复制到另一个结构只需用等号即可
定义: struct
Example: public struct Subscriber //创建Subscriber结构
{
public long SubscriberID;
public string FirstName;
public string MiddleName;
}
2.枚举 – 一组表示特定的预定义值的整数
定义: enum
Example: public enum TimeOfDay //定义TimeOfDay枚举
{
Morning = 0;
Afternoon = 1;
Evening = 2;
}
3.4.2 引用类型
1.类
每个C#可执行文件至少有一个类,程序的入口是Main方法,它封装了数据以及访问和操作这些数据的功能。
2.接口
用于类的定义功能,包含属性、方法、事件等,但不能补实例化,没有定义函数执行方式。
3.委托
用于引用方法的类型与C++的指针,可能调用类的指定方法。
4.数组
定义:[]
Example: int[] Integers //定义一个int类型的Integers数组
初始化数组的大小使用new
Example: int[] Integers = new int[32] //初始化数组的大小为32
用{}初始数组
Example: string[] eString = {“first element”,”second element”,”third element”};
string[] eString = new string[] {“first element”,”second element”,”third element”};
初始化数组要注意的问题:
1. 不能用变量设置数组的大小。
2. 可能用常量来定义数组的大小。
3. 如果希望数组的大小是动态变化,就需创建ArrayList对象,该对象在System.Collections名称空间中。
用0下标引用数组的第一个变量
数组的一些属性和方法:
Length – 取数组的大小
GetLength – 取多维数组某一维的大小
Array.Sort(String) – 对数组升序排序 (用数组名作参数)
Array.Reverse(String) – 对数组反序排序(用数组名作参数)
多维数组的定义:用逗号来分隔各个维
Example: string[,] eString; //定义一个二维的eString数组
初始化大小: double[,] Matrix = new double[10,10];
string[,] BeatleName = {{“Lennon”,”John”},{“McCartncy”,”Paul”}};
3.4.3 类型转换
1. 隐式转换方式
可以自动进行,值不会发生任何变化,从范围小的转到范围大的或从无符号的整数转换为大小相同的有符号整数,如从整数转换为浮点数。
2. 显式转换方式
如果会发生丢失数据时只用使用显式转换。
定义:在修改值之前,把要转换的类型放在贺括号中。
Example: long val = 3000;
int i = (int)val;
3.4.4 封箱(Boxing) 和 拆箱(Unboxing)
封箱用于把值类型转换为引用类型,拆箱用于把引用类型转换为值类型。
注意:把引用类型转换为值类型时,必须确保得到的值变量有中够的空间存储类型的值中的所有字节。
3.5 变量
定义:[modifiers] datatype identifier;
Example: public int i; //定义public访问级别的变量i
在多变量声明中,不能指定不同的修饰符或数据类型。
Example: public int x ,private byte y; //error
3.5.1 标识符
3.5.2 变量的范围
变量只能在相应的作用范围内起作用。
Example:
class class1
{
int a;//变量a在整个class内起作用
public void A()
{
int b; //变量b只能在方法A内起作用
int a; //error,因为出方的变量a在这里还起作用,不能有同名
}
}
3.5.3 变量修饰符
1.访问修饰符
访问性 说明
public 在任何地方都可以访问它
internal 只能在当前程序中被访问
protected 只能在它所属的类型中被访问,或在派生类型中被访问
protected internal 只能在当前程序中被访问,或在派生类型中被访问
private 只能在它所属的类型中被访问
2.静态和实例变量
静态变量 - 在调用时无需先实例化它所属的类
修饰符: static
3.只读变量
修饰符: readonly
变量被初始化后不能修改它的值,静态只读字段不能在实例构造函数中设置,也不能在静态构造函数中实例化只读字段。
例外的是,如果当变量声明为一为类或结构的字段时,给变量指定了一个值,就不能重新设置只读字段的值,而可以在构造函数中重写这个值。
3.6 常量
关键字: const
Example: const int a = 100; //定义常量a并设为100
注意必须在声明时初始化,常量是静态的,但不用static来定义。
3.7 运算符
3.7.1运算符的简化操作
x++ , ++x x = x + 1 (第一种形式是在取x值后加1,第二种形式是取值前加1
x-- , --x x = x – 1 (第一种形式是在取x值后减1,第二种形式是取值前减1
x += y x = x + y
x -= y x = x - y
x *= y x = x * y
x /= y x = x / y
x %= y x = x % y
x >>= y x = x >> y
x <<= y x = x << y
x &= y x = x & y
x |= y x = x | y
x ^= y x = x ^ y
3.7.2 三元运算符
语法 :condition ? true_value : false_value
3.7.3 checked 和 unchecked 运算符
如果把一个代码块标记为checked,CLR就会执行溢出检查,如发生溢出,就抛出异常。
用checked进行编译,就可以检查程序中所有未标记代码中的溢出。
Example:
byte b = 255;
checked
{
b++;
}
运行这段代码,就会得到一个错误信息
byte b = 255;
unchecked
{
b++;
}
程序不会抛出异常,但会丢失数据
3.8 流控制
3.8.1 条件语句
1.if
if (condition) //整数类型不能隐式转换为bool类型
statement(s) //如果多个一行要用{}组合成块
else
statement(s) //如果多个一行要用{}组合成块
2.switch
switch (参数)
{
case 值1: //case的值必须是常量表达式,不能为变量
statement(s); //不需使用{}组成块
break; //结束switch ,如没有break就会继续运行到有break为止
case 值2:
statement(s)
break;
default: //参数的值在case找不到就执行这里
break;
}
3.8.2 循环
1.for
for (initializer; condition; iterator)
statement(s)
2.while //循环前不知道要循环多少次
while (condition)
statement(s)
3.do … while
do
{
statement(s)
} while(condition);
4.foreach – 只能用于数组
foreach(int 变量名 in 数组名)
statement(s)
3.8.3 跳转语句
1.goto
2.break – 退出循环
3.continue – 退出当次循环,然后跳转下一次循环
4.return – 退出类的方法
3.8.4 using块语句
确保在使用完资源密集型的对象后就处理它们
using(object)
{
//code using object
}
3.9 程序的结构
3.9.1 类
1.类的成员
(1)数据成员 – 包括字段、常量和事件
字段 – 是与类相关的变量
常量 – 与关系与字段一样
事件 – 是类的成员,它可以让调用者在特定的行为发生的时间。
(2)函数成员 - 包括方法、属性、构造函数和析构函数、运算符和索引符
方法 – 是与某个特定功能相关的函数.
属性 – 用于访问类的公共字段类似的方式访问的函数
构造函数 – 在实例化对象时调用的函数
析构函数 – 在对象被析构时调用
运算符 - 类可定义自己的运算符
索引符 – 使对象以数组和集合方式访问
2.方法
(1) 方法的声明
修饰符 返回值的类型 方法名 (参数)
{
return 返回
}
6.2 用户定义数据类型转换
隐式定义: implicit
Example: public static implicit operator float(Currency value) //Exchange from Currency into float
显式定义: explicit
Example: public static explicit operator Currency(float value) //Exchange from float into Currency
注意: 如果声明为隐式,可以隐式或显式使用;如果声明为显式,只能显式使用。
1.类之间的数据类型转换
.如果某类与另一个类有直接或间接继承关系,就不能在这两个类进行数据类型转换。
.必须在源或目标数据类型定义的内部定义。
2.编译器已经提供基类与派生类之间的转换
.派生类可转为基类
.基类不可转为派生类
6.2.2 多重数据类型转换
如果在没有可用的直接转换方式,.net就会寻找一种方式,把几种转换合并起来。
例如,我们定义了Currency与float的转换,当要从Currency转换long是,编译器会先把Currency转换为float后转换为long,因为float与long的转换.net已定义,编译器会自动找已定义的转换的方法。
6.3 委托
当要把方法传送给其它方法时,需要使用它;简单讲就是把方法作为参数据传递给其它方法的规则;可用来调用类内的不同方法。
委托的定义:delegate
Example:delegate double TwoLongsOp(long L1,long L2);//定义TwoLongsOp委托,有两个long参数,返回double
6.3.1 多点委托 - 同时委托多个方法
6.4 事件 – 实际上是委托的一种特殊形式
OnClick()事件
void OnClick(object sender,EventArgs e)
{
//code to handle event
}
第一个参数是生成事件的对象引用,则事件发生器要自己传送一个它本身的引用
第二个参数是对System.EventArgs的引用或派生类
第7章 C#和基类
7.1 System.Object
7.1.1 对引用对象进行等于比较
7.1.2 对值类型进行等于比较