1. .NET框架具有两个主要组件:公共语言运行时和框架类库。
2. .NET框架结构
.NET框架是.NET最基础的框架,它提供了创建、部署和运行.NET应用的环境。包含CLR和框架类库,并且支持多种开发语言。
Java是一个跨平台的语言,而.NET是一个跨语言的平台。 在Linux上也可以运行.NET程序。
clr是所有.NET应用程序运行时环境,是所有的.NET应用程序都要使用的编程基础。< xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:office:office" />
clr公共语言运行时 cls公共语言规范 cts通用类型系统
cts 所有的.NET语言共享一类型系统,实现无缝互操作。
cls 是一种最低的语言的标准。制定了一种以.NET平台为目标的语言所必须支持的最小特征,以及该语言与其他.NET语言之间实现互操作性所需要的完备特征。
1. 框架类库的使用
框架类库中有数量非常庞大的命名空间和类,使用方便,功能强大。
2. 命名空间与Java中的package相似。
在C#中命名空间只是一种逻辑上的结构,它允许所组织的类文件的物理存放位置与逻辑结构不一致,而Java中类文件的物理结构必须与包的结构一致。
定义一个命名空间是关键字“namespace”后面跟命名空间的名字和命名空间的主体。
引用命名空间的方法和Java相似。使用“using”关键字。第2章 用对象思考:属性和方法
1. 类和对象
类成员 | 数据 | 字段 |
常量 | ||
事件 | ||
函数 | 方法 | |
属性 | ||
构造函数 | ||
析构函数 | ||
运算符 | ||
索引器 |
类的属性 对象所拥有的特征,在类中表示时称为类的属性。
类的方法 对象执行的操作称为类的方法。
2. 类和对象的关系
a) 由对象归纳为诶类,是归纳对象共性的过程。
b) 在类的基础上,将状态和行为实体化为对象的过程称为实例化。
3. 类和对象的使用
a)将类实例化为对象
b)访问对象的属性或者方法
4. 定义类和类的成员
访问修饰符 class <类名>
{
//类的主体
}
定义字段是第一个字母小写,最好加下划线“_”。
5. 使用C#中的属性
在C#中通常不会直接访问类中的字段,而是通过get和set访问器来访问,这种实现方式我们称为属性。
get访问器用来返回相应的私有字段的值,用return来返回。
set访问器用来设定相应的私有字段的是,可以看作是一个隐含的输入参数,
定义一个属性时,类型必须与它所访问的字段类型一致。
6. 在类中使用方法
类和对象中的另一个主要成员是方法,方法用来表示类和对象的行为。当需要类的对象做一件事情的时候,就需要给类添加方法。
语法
访问修饰符返回类型方法名(参数)
{
//方法体
}
方法的返回值类型可以是基本的数据类型,也可以是基本的对象类型object,还可以是void,如果是void,则方法不需要返回值。
方法的参数
a)使用值传递,在方法中对参数值的更改在调用后不能保留。
b)使用ref方式传递,可以将参数值的更改保留。
c)out关键字修饰的参数在方法中的修改,也会保留。
如果一个方法有输出参数,则必须对输出参数进行赋值。
用ref和out都可以将更改保留参数。 但是ref侧重于修改,out则更侧重于输出。
7. 方法的重载 的方式主要有两种
c) 参数是不同类型的重载:public double Sum(double para1,double para2)
d) 参数个数不同的重载:public int Sum(int para1,int para2,int para3)
8. 静态方法和实例方法
需要使用类的实例对象来调用的方法,通常称为实例方法。
静态方法是用“类名.方法名”来调用。
静态方法 | 实例方法 |
static关键字 | 不需要static关键字 |
类名调用 | 实例对象调用 |
可以访问静态成员 | 可以直接访问静态成员 |
不可以直接访问实例成员 | 可以直接访问实例成员 |
不能直接调用实例方法 | 可以直接调用实例方法和静态方法 |
调用前初始化 | 实例化对象是初始化 |
9. 使用构造函数创建对象
构造函数用于在创建实例时对对象进行初始化。
使用构造函数时注意以下几个问题:
e) 函数名和类名相同
f) 构造函数无返回值
g) 一般为public类型
h) 在构造函数中不要对类的示例做初始化以外的事情。不要尝试显式的调用构造函数,也就是直接去调用。
第3章 用对象思考:值类型和引用类型
1. 在程序中使用常量
在C#中定义常量加const 常量是静态只读的字段。
语法
访问修饰符 const 数据类型常量名 = 值
常量在程序的使用过程中是不会发生变化的变量。如果我们在程序中强制修改它的值,就会发生错误。
注意:
A. 必须在声明是进行赋值,指定后就不能再修改
B. 常量总是静态的
C. 指派给常量的表达式中不能有变量
D. 如果需要在表达式中,则需要只读只读字段
E. 常量不占用内存。
2. 使用枚举避免不合理赋值
枚举是一个特殊的类,和类相似。
在C#中使用enum关键字来定义一个枚举,它表示一组有限的值,对可能的值进行约束。
例:
public enum Genders
{
Male,Female
}
给枚举成员赋值
枚举允许用描述性的名称表示整数值。
例:
public enum Gender
{
Male=0,Female = 1
}
int genderNum = (int)stu.Gender;
将枚举得值转换为int型,就可以得到定义枚举时所指定的整数值。
还可以从一个字符串中获取枚举的值
stu.Gender = (Genders)(Enum.Parse(typeof(Genders),”Female”))
使用枚举的好处:
A. 枚举可以使代码更易于维护,有助于确保给变量指定合法的、期望的值。
B. 枚举更易于输入,如果我们使用枚举赋值,则只要输入枚举名,然后打一个“.”就能将所有的值显示出来,减少了按键次数,能够让我们回忆起可选的值。
C. 枚举使代码更清晰,允许描述性的名称表示数据,使用时直观方便。
枚举的主体中不可以定义属性和方法。
3. 结构 中的构成和类非常相似。
可以通过RGB方式来表示(Color red = Color.FromArgb(255,0,0))。
A. 结构的定义
语法
访问修饰符struct 结构名
{
定义结构成员
}
B. 结构的使用
结构的构成和类很相似,在使用结构的时候,可以不用new,直接定义就可以了,但是必须为结构的成员赋初值,直接用结构的名字访问成员就可以了。
C#提供给结构一个无参的构造函数,所以使用结构是可以不用new关键字。
C. 结构与类的区别
类和结构的区别
| 类 | 结 构 |
不同点 | 引用类型 | 值类型 |
可以被继承 | 不能被继承 | |
可以有默认构造函数 | 不可以有默认构造函数 | |
可以添加无参的构造函数 | 可以添加构造函数,但它们必须带参数 | |
创建对象必须使用new | 创建对象可以不用new | |
结构中给字段赋值是错误的 | 类中可以给字段赋值 | |
相同点 | 都可以包含字段、方法 | |
都可以实现接口 |
类是引用类型,结构是值值类型。
4. 值类型
值类型院子System.ValueType家族。
值类型主要包括基本的数据类型、结构类型和枚举类型等。
5. 引用类型
引用类型源于System.Object家族,它存储的是对值的引用。
值类型在栈内存上开辟一部分空间。
引用类型在栈内存上合堆内存上都开辟了一部分空间。
6. 装箱和拆箱
.NET中的类型分成了值类型和引用类型,但是它们之间可以相互转换的。
把值类型转换成引用类型的过程称为装箱,
把引用类型转换为值类型称为拆箱。
7. 不同类型的参数传递
a) 值方式参数传递
需要使用ref修饰。
b) 引用方式参数传递
不需要ref修饰
8. 细分值类型和引用类型
结构作为值类型,类作为引用类型。
数据类型分类
类 别 | 描 述 | |
值类型 | 基本数据类型 | 整型:int |
长整型:long | ||
浮点型:float | ||
字符型:char | ||
布尔型:bool | ||
枚举类型 | 枚举:enum | |
结构类型 | struct | |
引用类型 | 类 | 基类:System.Object |
字符串:string | ||
自定义类:class | ||
接口 | 接口:interface | |
数组 | 数组:int[],string[] |
自定义类型中除了枚举和结构,其他的都是引用类型。
int和float是值类型,它们是结构。
9. 在类中使用索引器
使用数组的索引来访问元素,必须非常清楚数组中的元素的索引,使用起来非常不方便,因为我们很容易记住学员的名字,但是很难记住它在数组中的位置。
所以在C#中使用索引器允许类和结构的实例按照与数组相同的方式进行访问,但它能够定义不同的访问方式来访问,而不仅仅是使用索引。
例: 使用索引器通过姓名检索 在MyClass类中将学员属性的类型由数组Student[]改为Student对象。添加一个Students类并加入索引器,然后将它的访问方式重载,使用姓名进行访问。
public Student this[int index]
{
get{return students[index];}
}
public Student this[string name]
{
get
{
int i;
bool found =false;
for(i =0; i <students.length;i++)
{
if(students[i].Name ==name)
{
found = true;
break;
}
}
if(found)
{
return students[i];
}
else
{
return null;
}
}
}
访问Student对象时,可以通过学员的姓名访问,也可以通过索引访问。
MyClass myClass = new MyClass(“T< xmlnamespace prefix ="st1" ns ="urn:schemas-microsoft-com:office:smarttags" />01”);
myClass.Students[2].SayHi();
myClass.Students[“周杰杰”].SayHi();
10. 索引器的特点及其应用
定义索引器的时候,要使用this关键字,而get和set访问器也类似于属性。索引器和数组属性有些类似,但是数组属性只能通过下标(索引)访问,而索引器可以通过重载它,从而自定义它的访问方式。
DataReader[“列名”],DataRow[“行名”]等,都是索引器。
11. 类图示表示类的结构和类与类之间关系的图表。
第4章 用集合组织相关数据
1. ArrayList
ArrayList类似于数组,但是数组的容量是固定的,而ArrayList的容量可以根据需要进行自动扩充。ArrayList可以根据类提供的方法,进行访问、新增、删除元素的操作,实现对集合的动态访问。
ArrayList类来自于System.Collections命名空间。在定义时可以不指定容量,也可以指定容量。 ArrayList只提供一维数组。
A. 给ArrayList添加元素
C#中为ArrayList添加元素的方法是Add(Object value),参数是要添加的元素。
ArrayList中的元素都会被转换为object引用类型然后保存。所以ArrayList中的所有元素都是对象的引用。此方法的返回值是一个int整型,用于返回所添加的元素的索引,该方法将对象插入到ArrayList集合的末尾处。
B. 存取ArrayList中的单个元素
ArrayList和数组很像,获取一个元素的方法和数组是一样的,通过索引index来访问,ArrayList中第一个元素的索引时“0”。 ArrayList添加元素时,可以添加任何我们想存储的对象,当添加到ArrayList中时会转换为Object型,所以在访问元素时必须把它们转换回本身的数据类型。
例:
Student stu1 = (Student)students[0];
stu1.SayHi();
C. 删除ArrayList中的元素
删除ArrayList中的元素有3种方式:
1) 通过RemoveAt(int index)方法删除指定index的元素。
2) 通过Remove(object value)方法删除一个指定对象名的元素。
3) 通过Clear()方法移除集合中的所有元素。
ArrayList添加和删除元素都会使剩余元素的索引自动改变。
D. 遍历ArrayList中的元素
可以使用for循环或者foreach循环来遍历ArrayList中的所有元素。
2. HashTable
使用HashTable可以通过关键字来访问一个集合中的某个元素对象。也可以删除元素。
在哈希表中,每个元素都是一个键/值对,而且是一一对应的,通过键(key)便可以查找到相应的值。
A. 给哈希表添加元素
哈希表属于System.Collections命名空间,给HashTable添加一个对象,要使用Add()方法。但哈希表的Add()方法有两个参数,一个表示键,一个表示键所对应的值。
B. 获取哈希表的元素
访问哈希表中的元素时,可以直接通过键名来获取具体值。由于值的类型是Object类,所以当得到一个值时也需要通过类型的转换得到正确的类。
C. 遍历哈希表 是一个无序存放的集合。
Environment.NewLine; 可以换行
由于哈希表不能够用索引访问,所以遍历一个哈希表只能用foreach()方法。
D. 删除哈希表的元素
语法:
public void Remove(Object key);
哈希表删除一个元素时使用的是它的Key值。哈希表也可以使用Clear()方法清除所有元素,用法和ArrayList相同。
3. 泛型和泛型集合
由于ArrayList和HashTable集合中的每个元素都是Object类,在添加元素时不会严格的类型检查。所以要引入泛型集合,在添加元素时就进行检查。
泛型的优点:
(1)泛型的性能高。无需类型转换。
(2)类型安全。泛型集合对它所存储的对象做了类型的约束,不是它所存储的类型是无法添加到泛型集合中。
4. 泛型集合List<T>
在System.Collection.Generic命名空间中。泛型集合List<T>的用法类似于ArrayList。
语法:
List<Student> students = new List<Student>();
“<T>”中的T可以对集合中的元素类型进行约束,T表明集合中管理的元素类型。
注意:实例化时后面要加上“()”。
5. 泛型集合Dictionary<K,V>
在System.Collections.Generic命名空间下。
它具有泛型的全部特征,编译时检查类型约束,获取元素时无须类型转换,存储数据的方式和哈希表类似,也是通过Key/Value键/值对保存元素的。
语法:
Dictionary<String , Student> students = new Dictionary<String , Student>();
<K,V>中的K表示集合中的Key的类型,V表示Value的类型。
6. 泛型总结
泛型集合的类型无需装箱和拆箱的操作,运用比较安全。
泛型的重要性主要体现在:
(1)解决了很多繁琐的操作问题,泛型集合无须类型转换,使编程更加便捷。
(2)提供了更好的类型安全性,控制在集合中对于不同类型的对象的胡乱使用。
(3)CLR可以支持泛型,使整个.NET平台都能够使用泛型。
第5章 文件读写与XML数据
静态类中的枚举不用static修饰因为它本身就是一个特列的类型就是一个静态类。
1. 读写文件
读写一个文件需要5个基本步骤
(1)创建一个文件流
(2)创建阅读器或者写入器
(3)执行读写操作
(4)关闭阅读器或者写入器
(5)关闭文件流
需要引入System.IO命名空间。using System.IO;
例:
FileStream myFs = new FileStream(“文件路径”,FileMode.Create); //创建文件流
StreamWriter mySw = new StreamWriter(myFs); //创建写入器
mySw.Write(“文件内容”); //将录入的内容写入文件
mySw.Close(); //关闭写入器
myFs.Close(); //关闭文件流
2. 文件流
a) 创建文件流
需要使用文件流FileStream类,它主要用于读写文件中的数据。
FileStream(String FilePath,FileMode),FilePath用于指定要操作的文件,FileMode指定如何打开文件的模式,是一个枚举类型。
Create:用指定的名称新建一个文件。如果文件不存在,则改写旧文件。
CreateNew:新建一个文件。如果文件存在会发生异常,提示文件已存在。
Open:打开一个文件,使用这个枚举值时,指定的文件必须存在,否则会发生异常。
OpenOrCreate:OpenOrCreate与Open成员类似,只是如果文件不存在,则用指定的名称新建一个文件并打开它。
b) 关闭文件流
文件流名.Close();
3. 文件读写器
a) StreamWriter写入器
创建文件流之后,要创建读取器或者写入器,StreamWriter类称为写入器,它用于将数据写入文件流,只要将创建好的文件流传入,就可以创建它的实例。
StreamWriter mySw = new StreamWriter(“创建好的文件流名”);
StreamWriter.Write():用于写入流,这个流是创建好的流
StreamWriter.WriteLine():用于写入一行数据,写入某些数据后跟换行符。
StreamWriter.Close():用于关闭写入器。
b) StreamReader读取器
StreamReader主要用于读取流中的数据。它的主要方法有:
? StreamReader.ReadLine():读取文件流中的一行数据,并返回字符串。
? StreamReader.ReadToEnd():从当前位置读到末尾,返回字符串。
? StreamReader.Close():用于关闭读取器。
4. 文件和目录操作
(一) File类和Directory类
File类的方法
方 法 | 说 明 |
Exists(string path) | 用于检查指定文件是否存在,该方法返回一个布尔值 |
Copy(string SourceFilePath,string DesinationFilePath) | 将指定路径的源文件中的内容复制到目标文件中,如果目标文件不存在,则在指定路径中新建一个文件 |
Move(string sourceFileName,string destFileName) | 将指定文件移动到一个新的路径 |
Delete(string path) | 删除指定的文件,如果指定的文件不存在,则不引发异常 |
Directory类的方法
方 法 | 说 明 |
Exists(string path) | 用于检查指定文件夹在磁盘上是否存在 |
Move(string sourceDirName,string destDirName) | 用于将文件或目录及其内容移到新位置 |
Delete(string, bool) | 删除指定目录,如果bool值为true,则删除子目录中的所有目录内容 |
(二) 静态类与非静态类
File类和Directory类在使用它们的方法是都不需要实例化,而是直接使用类名.方法名()的方式调用。
静态类和非静态类的区别
静 态 类 | 非静态类 |
用static修饰 | 不用static修饰 |
只包含静态成员 | 可以包含静态成员 |
不可以包含实例成员 | 可以包含实例成员 |
使用类名调用静态成员 | 使用实例对象调用非静态成员 |
不能被实例化 | 可以被实例化 |
不能包含实例构造函数 | 包含实例构造函数 |
5. XML概述
XML称为可扩展标记性语言。
XML的特点:
XML中用于描述数据的各个节点可以自由地扩展。
XML文件中的节点区分大小写。
XML中的每对标记通常称为节点,它们是成对出现的,用来描述这个节点存储的内容。
操作XML的对象属性和方法
对 象 | 属性和方法 | 说 明 |
XmlDocument | DocumentElement属性 | 获取根节点 |
ChildNodes属性 | 获取所有子节点 | |
Load()方法 | 读取整个XML的结构 | |
XmlNode | InnerText属性 | 当前节点的值 |
Name属性 | 当前节点的名字 | |
ChildNodes属性 | 当前节点的所有子节点 |
第6章 用对象思考:继承
1. 继承概述
为了减少程序中相同的代码,需要用到继承,来减少在编代码时大量重复的代码,造成的冗余。
在C#中,一个类可以继承另一个类。被继承的类称为父类或者基类,继承其他类的类称为子类或者派生类。
继承是面向对象编程中一个非常重要的特性。在有继承关系的两个类中,子类不仅具有自己独有的成员,还具有父类的成员。
如果一个类继承另一个类语法如下:
例:
class Student:Person class Teacher:Person。
2. protected访问修饰符与base关键字
用protected修饰符修饰的成员允许被其子类访问,而不允许其他非子类访问。
也可用override重写把基类方法替代。
给一个方法添加virtual时,此方法为虚方法。
子类可以访问父类内部字段当用不同的修饰符修饰时
public、private、protected的区别
修饰符 | 类内部 | 子 类 | 其他类 |
public | 可以 | 可以 | 可以 |
private | 可以 | 不可以 | 不可以 |
protected | 可以 | 可以 | 不可以 |
在C#中还有一个关键字base,它用于表示父类。可以访问父类的成员。
例如:调用父类的属性,调用父类的方法,调用父类的构造函数。
在用base()调用父类的构造函数的时候,只需要指定变量名,这个变量名必须与父类中的构造函数中的一致。
3. 继承的特征
a) 继承的传递性
b) 继承的单根性 不能同时继承多个父类。
c) 密封类 用sealed修饰的类不能够被继承。称为密封类。
4. 编写子类构造函数的注意事项
a) 隐式调用父类构造函数
如果子类的构造函数没有使用base关键字指明调用哪个构造函数,则父类必须提供一个默认的无参构造函数。
b) 显式调用父类构造函数
如果父类没有提供默认的无参构造函数,那么子类的构造函数必须明确指明调用的是哪个父类的有参构造函数。
注意:子类的无参构造函数调用父类的有参构造函数时,要给参数赋值。
第7章 用对象思考:多态
1. 多态 是指两个或多个属于不同类的对象,对于同一个消息(方法调用)作出不同响应的方式。
多态分为两种:
一种是编译时的多态,是编译时决定用哪个方法。
另一种执行时的多态,是执行时才决定用哪个方法。
2. 抽象类和抽象方法
a) 抽象方法是一个没有实现的方法,通过在定义方法时增加关键字abstract可以声明抽象方法。
语法:
访问修饰符 abstract 返回类型方法();
注意:抽象方法没有闭合的大括号,而是直接加一个分号“;”,也就是说,它没有包括方法执行逻辑的方法体。
b) 含有抽象方法的类必然是抽象类。
语法:
访问修饰符 abstract class 类名
抽象类中的方法并不一定都是抽象方法;抽象类也可以容纳有具体实现的方法,或者称为具体方法。但是,含有抽象方法的类必然是抽象类。
抽象类不能被实例化;不能是密封或者静态的。
3. 抽象类和抽象方法的使用
A. 重写抽象方法
当一个抽象基类派生出一个子类时,子类将继承基类的所有特征,包括它的未实现的抽象方法。抽象方法必须在其子类中实现,除非它的子类也是抽象类。在子类中实现一个抽象方法的方式是使用override关键字来重写抽象方法。
语法:
访问修饰符 override 返回类型方法()
B. 抽象类和抽象方法的应用场合
由于抽象父类中提供的抽象方法,要在子类中实现。因此,父类提供了一个功能或者规定,约束子类的行为。
4. 里氏替换原则
子类可以替换父类并且出现在父类能够出现的任何地方。但是反过来,父类对象是不能替换子类的。这种特征称为“里氏替换原则(LSP)”
里氏替换的两个关键技术
a) is操作符的使用
if(obj is string)
{
}
如果所提供的对象可以强制转换为所提供的类型而不会导致引发异常,则is表达式的结果为true
b) as操作符的使用
它用于两个对象之间的类型转换。
例:
Student stu = Student[i] as Student;
5. 虚方法的实际应用
a) 使用虚方法实现多态
在C#中用virtual关键字修饰的方法称为虚方法,虚方法可以具有的实现。也可以被重写。
在父类中定义虚方法,然后在子类中可以重写虚方法。
语法:
访问修饰符 virtual 返回类型方法()
{
//方法体
}
方法重载返回类型可以不相同。
b) 重写Equals()方法
每个Object对象都有一个Equals()方法,用于确定两个实例对象是否相等。
语法:
public virtual bool Equals(Object obj)
虚方法与抽象方法的区别
虚方法 | 抽象方法 |
用virtual修饰 | 用abstract修饰 |
要有方法体, | 不允许有方法体 |
可以被子类override | 必须被子类override |
除了密封类外都可以写 | 只能在抽象类中 |
6. 面向对象的三大特性
a) 非装:保证对象自身数据的完整性、安全型
b) 继承:建立类之间的关系,实现代码复用,方便系统的扩展
c) 多态:相同的方法调用可实现不同的实现方式
第8章 用对象思考:接口
1. 自定义对象的排序
集合中的元素可以排序。它们都有默认的排序方法Sort();
2. IComparable接口
语法:
public interface IComparable
{
int CompareTo(Object obj);
}
这个接口中的方法用于将当前实例与另一个对象比较大小一个类如果实现了这个接口中的CompareTo方法,意味着这个类的对象是可比较的,它返回一个整型的返回值,返回值的含义:
n 如果返回值小于0,则当前实例小于obj
n 如果返回值大于0,则当前实例大于obj
n 如果返回值等于0,则当前实例等于obj
CompareTo方法中编写代码:
例: return this.Age.CompareTo(other.Age);
3. 接口概述
a) 接口中可以包含属性、方法、索引器、事件等。但是都不能够实现。
b) 定义一个接口的名称通常都以“I”开头。
c) 习惯的说法是实现了一个接口、继承了一个类
d) 实现一个接口的语法与继承类似
e) 如果类已经继承了一个父类,则以“,”分隔父类和接口,并且是先继承后实现接口;
4. 泛型接口
例如:IComparable<T>就是一个泛型接口。此接口有CompareTo()方法,用于比较。
5. IComparer<T>比较器
用IComparable<T>接口 它的实现接口的比较方法时指定的,也就是排序一开始就确定了。所以可以使用IComparer<T>接口,实现其他的排序。
它提供了Sort()方法提供一种重载。
语法:
Public void Sort(IComparer<T> comparer)
IComparer<T>泛型接口,有一个未实现的方法int Comparer(T x,T y),用于比较两个对象的大小。
6. 接口和实现类
实现一个接口必须实现它提供的方法、属性等。和抽象类相似。
抽象类与接口的区别
| 抽 象 类 | 接 口 |
不同点 | 用abstract定义 | 用interface定义 |
只能继承一个类 | 可以实现多个接口 | |
非抽象派生类必须实现抽象方法 | 实现接口的类必须实现所有成员 | |
需要override实现抽象方法 | 直接实现 | |
相似点 | 不能实例化 | |
包含未实现的方法 | ||
派生类必须实例为实现的方法 |
(1) 接口:接口是某类行为或功能的抽象,是一种规范或者标准,或者说是一种契约。
(2) 抽象类:对具体对象的最高抽象,这个对象拥有自己的最基本特征。
抽象类只需子类实现它的抽象方法,接口必须实现所有成员。
第9章 序列化与反射
一、序列化与反序列化
要序列化一个文件需要引用命名空间
using System.Runtime.Serialization.Formatters.Binary;
要序列化某个类要在类的上面添加[Serializable];
1. 序列化 一个类文件
要用到Serialize()方法;
语法:
public void Serialize(Stream serializationStream,Object graph)
serializationStream是指定序列化过程的文件流
graph是要保存的对象
例:
public void Save()
{
FileStream fileStream = null;
//定义一个文件流
fileStream = new FileStream(“文件名”,FileMode.Create);
//二进制方式
BinaryFormatter bf = new BinaryFormatter();
//序列化保存配置文件对象
bf.Serialize(fileStream,对象名称);
}
2.反序列化 一个类文件
要用到Deserialize()方法
语法:
public Object Deserialize(Stream serializationStream)
public void Load()
{
FileStream fileStream = null;
fileStream = new FileStream(“文件名”,FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
对象名 = (类型)bf.Deserialize(fileStream);
}
二、程序集与反射
一个编译好的.exe文件,称为程序集。
程序集清单的内容
信 息 | 说 明 |
程序集名称 | 指定程序集名称的文本字符串 |
版本号 | 主版本号和次版本号,以及修订号和内部版本号 |
区域性 | 有关该程序集支持的区域性或语言的信息 |
强名称信息 | 如果已经为程序集提供了一个强名称,则为来自发行者的公用 |
程序集中所有文件的列表 | 构成该程序集的文件 |
类型引用信息 | 控制对该程序集的类型和资源的引用如何映射到包含其声明和实现的文件中 |
有关被引用程序集的信息 | 该信息用于从程序集导出的类型 |
程序集属性列表
属 性 | 说 明 |
AssemblyCompany | 指定公司名 |
AssemblyTitle | 程序集的描述性名称 |
AssemblyDescription | 描述程序集或产品 |
AssemblyConfiguratioin` | 指定建立信息,例如零售或者调试信息 |
AssemblyProduct | 指定程序集所属产品的名称 |
AssemblyCopyright | 包含版权和商标信息 |
AssemblyVersion | 程序集的版本号 |
反射可以获取已加载的程序集和在其中定义的类型(如类、接口和值类型)的信息。也可以使用反射在运行时创建类型实例,以及调用和访问这些实例。