Ildasm:微软中间语言编译器。
devenv:运行打开VS2008。
第 1 章:理解.NET Framework 与 C#
.NET 的特征:1. 可以跨设备。
2. 可以跨语言。
3. 统一的开发模式。
.NET框架的两个组件:1 . 公共语言运行时。(CLS 公共语言规范 和 CTS 通用类型系统)
2. 框架类库。
面向对象编程的特点:1.可复用性
2.可扩展性
3.易维护性
4.灵活性
System.Data :用于访问 ADD.NET
System.Windows.Forms :用于开发Windows 应用程序
System.Collections.Generic :可以使用泛型
System.Net :可以对网络协议进行编程
System.Security :提供系统的安全控件功能
第 2 章:用对象思考,属性和方法
面向对象:1. 封装 ( 实现数据的安全性 ):保证对象自身数据的完整性、安全性。
2. 继承 ( 实现代码的重用性、可维护性):建立类之间的关系,实现代码的复用,方便系统的扩展。
3. 多态(实现代码的灵活性 1.Overload:重载。2.Override:重写):相同的方法调用可实现不同的实现方式。
方法的重载:重载是多态的一种,通过多态实现代码的灵活性。
重载的实现方式:1. 所有的方法必须在同一个作用域里(同一个类)。
2. 方法名完全一样(括号里的参数个数,位置,类型可以不一样)。
3. 通过参数列表来决定调用哪个方法。
重写的实现方式:1. 一定要有继承关系。
2. 在子类和父类中,必须有一致的方法签名(方法声明)。
被重写的父类方法,必须是抽象方法或虚方法。
子类中要重写的方法,必须用override方法。
3. 必须用父类的引用来引用子类对象。
对象:万物皆对象。 (类似于 用户自定义的类型)
类:描述一组相似对象的共性。 (类似 变量)
类的内部区域:1. 声明区:字段 ,属性
2. 功能区:方法
实例化:创建一个对象。
类名 别名 = new 类名(); //实例化对象
方法:1. 方法的声明(访问类型,方法名……..)
2. 方法体
字段:用来表示与类和对象关联的数据。
采用Camel(骆驼)命名法 ,用来访问属性。一般把字段设为private(私有)的。
属性:用来表示类的状态。(只读属性:get , 只写属性:set ,读写属性:get ,set )
采用 Pascal 命名法。 安全性,私密性好。 简洁。(属性对字段进行操作)
方法:用来标识类的行为。
采用 Pascal 命名法。
静态:static ,属于类的方法 (只能通过类名调用)类名·方法名
非静态:属于对象的方法。(对象名· 方法名)
静态方法与实例方法的区别:
静态方法 | 实例方法 |
Static 关键字 | 不需要 static 关键字 |
类名调用 | 实例对象调用 |
可以访问静态成员 | 可直接访问静态成员 |
不可以直接访问实例成员 | 可以直接访问实例成员 |
不能直接调用实例方法 | 可以直接调用实例方法和静态方法 |
调用前初始化 | 实例对象时初始化 |
类存在,类的方法也存在,对象的方法不一定存在(只用实例化,对象才存在)
封装的好处:1. 避免使用非法数据赋值。
2. 保证数据的完整性。
3. 避免类内部发生修改时,导致整个程序的修改。
构造函数:用来初始化对象的属性。
1. 构造函数与它所属的类同名。
2. 一个类中没有显示定义构造函数则会生成一个默认的无参构造函数,否则,不生成。
Public 类名 () { }
3. 构造函数无返回值。
4. 构造函数自动调用。
在访问一个类的时候,系统将最先执行构造函数中的语句,构造函数也可以重载,可以初始化不同数量的属性,这样传入的参数数量不同。
构造函数注意事项:
1. 一个类的构造函数名通常与类名相同。
2. 构造函数没有返回值。
3. 一般情况下,构造函数总是public类型的。
4. 在构造函数中不要对类的示例做初始化以外的事情。
This :代表的是当前的对象。我们可以用this 关键字来访问它的成员。
传值的方式:
1. 值传递:ref 侧重于修改。
2. 引用传递。
3. out 传递:参数只用于输出,不能传入参数,侧重于输出。
4. params 传递:动态数组。
第 3章:用对象思考,值类型和引用类型
变量:相当于一个容器。在程序中不能被修改,适用于经常使用,且不能被改变的数据。
常量:不变的量,const (值不变,易维护)
在什么时候使用常量:1.用于在程序中一旦设定就不允许被修改的值。
2.用于在程序中被经常引用的值。
枚举:是一组描述性的名称。(关键字:enum )
枚举是特殊的整型。只能包含常量值。
枚举相当于一个列表。(MessageBox 就是一个枚举)
枚举的好处:1. 使代码更易于维护。
2. 更易于输入。
3. 使代码更清晰。
结构:是把一系列相关的变量组织成为一个单一的实体。(关键字:struct )
类和结构的区别:
| 类 | 结构 |
不同点 | 引用类型 | 值类型 |
可被继承 | 不能被继承 | |
有默认构造函数 | 不可以有默认构造函数 | |
可添加无参的构造函数 | 可添加构造函数,但必须带参 | |
创建对象必须使用new | 创建对象可不用new | |
结构中给字段赋值是错误的(初始值) | 类中可以给字段赋值 | |
可以析构函数 | 不能有析构函数 | |
相同点 | 都可以包含 字段 ,方法 ,属性 | |
都可以实现 接口 |
类和结构:存储值的位置不同,传值方式不同。
数据类型分类:
值类型:(存储在“ 堆栈”中):空间小,提取速度快。
1.基本数据类型:
整型:int
长整型:long
浮点型:float
字符串:char
布尔型:bool
2.枚举类型:枚举:enum
3.结构类型:结构:struct
引用类型:(存储在“ 堆”中) :空间大,提取速度慢。
1. 类:
基类:System.Object
字符串:string
自定义类:class
2. 接口:interface
3. 数组:int[] , string []
装箱:值类型转换成引用类型。(装、拆箱 消耗性能)
拆箱: 引用类型转换成值类型。
索引器:可以是使用索引访问,也可以自定义访问方式。
是一个方法,访问字段数组中的某个元素。
1. 定义一个索引器时,要使用this关键字,而get 和 set 访问器也类似于属性。
2. 索引器可以重载。(一个类可有多个索引器)
第 4 章 : 用集合组织相关数据
数组:存储相同类型。
一维数组:
多维数组:对等数组 和 交错数组,可节省空间但操作麻烦。
数组的缺点:1.大小是固定的。
2. 数组中值类型相同。
3. 对数组中的元素操作不方便。
集合:1.可伸缩大小,动态的。
2.可存储任何类型。
3.对数组中的元素操作方便。
集合的缺点:1.性能不高。(因装箱 和 拆箱 操作,导致)
2.安全性不高。
哈希表(Hashtable):通过建(key)和值(value)来组织。
语法:public void Add(Object value)
删除哈希表:public Remove(Object key)
泛型集合:结合了集合与数组的优点。(可以作为类中的一个属性,使泛型集合必须实例化)
1. 数据类型明确。2.性能高,安全性好。3.无需类型转换。
定义一个List<T> 泛型集合:List<A> a = new List<A>();
(T表明集合中管理的元素类型)
定义一个Dictionary<K,V>泛型集合:
Dictionary<string , A> a = new Dictionary <string , A>();
( <K,V>中的K 表示集合中的 Key 的类型 , V 表示Value 的类型 )
List<T> 和 ArrayList 的区别:
| List<T> | ArrayList |
不同点 | 对所保存的元素做 类型约束 | 可以添加 任何类型 |
添加/读取 无须拆箱、装箱 | 添加/读取 需要拆箱、装箱 | |
相同点 | 通过 索引器 访问集合中的元素 | |
添加元素的方法 相同 | ||
删除元素的方法 相同 |
Dictionary <K,V> 和哈希表的对比:
| Dictionary<K,V> | Hashtable |
不同点 | 对应保存元素做 类型约束 | 可以添加 任何类型 |
添加/读取 无须拆箱、装箱 | 添加/读取 需要拆箱、装箱 | |
相同点 | 通过 key 获得 Value | |
添加元素方法相同 | ||
删除元素方法相同 | ||
遍历方法相同 |
泛型的重要性:
1. 解决了很多繁琐的操作问题。
2. 提供了更好的类型安全性。
3. CLR(公共语言运行时)可以支持泛型。
第 5 章 : 文件读写与XML
程序中的数据通常保存在内存中的,当程序关闭后,这些内存中的数据就会被释放,
所以如果想保存程序中的数据或者说程序计算的结果 --- 数据持久化。
数据库:适用于大批量的包含复杂查询的数据维护。
文件:适合于相对简单的数据保存。(用来保存特定的数据)
读写一个文件需要以下 5 个步骤:
1. 创建文件流。
2. 创建阅读器 或者 写入器。
3. 执行读写操作。
4. 关闭阅读器 或者 写入器。
5. 关闭文件流。
流:是一个用于数据传输的对象。
FileMode:指定如何打开文件的模式,它是一个枚举类型。
Create:用指定的名称新建一个文件。如果文件存在,则改写旧文件。
CreateNew:新建一个文件。
Open:打开一个文件。
OpenOrCreate:与Open成员类似,只是如果文件不存在,则用指定的名称新建一个文件并打开它。
StreamWriter 写入器:
1. StreamWriter.Write():用于写入流,这个流就是我们创建好的流。
2. StreamWriter.WriteLine():用于写入一行数据,写入某些数据后跟换行符。
3. StreamWriter.Close():用于关闭写入器。
StreamReader 读取器:
StreamReader.ReadLine():读取文件流中的一行数据,并返回字符串。
StreamReader.ReadToEnd():从当前位置读到末尾,返回字符串。
StreamReader.Close():用于关闭读取器。
File类的方法:(用于对文件进行操作,如:复制、移动、删除 …)
方 法 | 说 明 |
Exists(string path) | 用于检查指定文件是否存在,返回一个布尔值 |
Copy(string SourceFilePath , String DestinationFilePath) | 将指定的路径的源文件中的内容复制到目标文件中,如果目标文件不存在,则在指定的路径中新建一个文件 |
Move(string sourceFileName , String desFileName) | 将指定文件移动到一个新的路径 |
Delete(string path) | 删除指定的文件,如果指定的文件不存在,则不引发异常 |
Directory类的方法:(用于对文件夹操作,它们都是静态类)
方 法 | 说 明 |
Exists(string path) | 用于检查指定文件夹在磁盘上是否存在 |
Move(string sourceDirName , String desDirName) | 用于将文件或目录及其内容移到新位置 |
Delete(string , bool) | 删除指定目录,如果bool 值为true,则删除子目录中的所有目录内容 |
File类 和 Directory类在使用它们的方法时都不需要实例化,而是直接使用 类名.方法()的方式调用。
静态类 与 非静态类 的区别:
静态类(File) | 非静态类(FileInfo) |
用 static 修饰 | 不用static 修饰 |
只包含 静态成员 | 可以包含静态成员 |
不可以包含实例成员 | 可以包含实例成员 |
使用 类名 调用 静态成员 | 使用 实例对象 调用 非静态成员 |
不能被实例化 | 可以被实例化 |
不能包含 实例构造函数 | 包含 实例构造函数 |
XML:可扩展标记性语言 (eXtensible Markup Language)
Html:描述网页的显示方式。
XML:描述内容。1.描述数据的各个节点可以自由地扩展。
2.XML文件中的节点区分大小写。
3.XML中的每对标记通常称为:“节点”。它们是成对出现的,用来描述这个节点存储的内容。
首先第一个节点称为 “根节点”。
跟节点里面所包含的节点称为它的 “子节点”。
XmlDocument对象可表示:整个XML文档。使用Load()方法将指定的XML文件读入 XmlDocument 对象。
它的属性DocumentElement 用来获取XML文件的根节点。
XmlNode 对象表示:一个XML中的节点。ChildNodes属性用于获取该节点下的所以子节点。
对 象 | 属性和方法 | 说 明 |
XmlDocument | DocumentElement | 获取根节点 |
ChildNodes | 获取所有子节点 | |
Load()方法 | 读取整个 XML 的结构 | |
XmlNode | InnerText属性 | 当前节点的值 |
Name属性 | 当前节点的名字 | |
ChildNodes属性 | 当前节点的所有子节点 |
树形控件:TreeView
第 6 章 : 用对象思考:继承
继承:一个类可以继承另一个类。
被继承的类称为 父类 或者 基类,继承其他类的类称为 子类 或者 派生类。
继承是面向对象编程中一个非常重要的特性。
在有继承关系的两个类中,子类不仅具有自己独有的成员,还具有父类的成员。
继承要符合 is a 的关系。(is a = 是)
继承很好的解决了代码复用的问题。
继承具有:1. 传递性。(如:class A :B ,class B :C ,则 A 也可以访问 C 的成员)
2. 单根性。(一个类不能够同时继承自多个父类)
被sealed 关键字修饰的的类称为:“密封类”,它不能被继承。
通过this 关键字可以访问类本身的成员,也可以访问由父类继承过来的属性。
Protected:被这个访问修饰符修饰的成员允许被其子类访问,而不允许其他非子类访问。
Public 、private 、 protected 的区别:
修 饰 符 | 类 内 部 | 子 类 | 其 他 类 |
Public | 可以 | 可以 | 可以 |
Private | 可以 | 不可以 | 不可以 |
Protected | 可以 | 可以 | 不可以 |
Base:它用于表示父类,可以用于访问父类中的成员。
Base关键字可以用于 调用父类的属性、方法、构造函数。
在子类中,如果不使用base 关键字来显示调用基类构造函数,则将隐式调用默认的构造函数。
如果重载的构造函数有一个没有使用base 关键字来指明调用父类那个构造函数,则父类必须提供一个默认的构造函数。
使用构造函数的每种情况必须明确声明,而不能期望自动调用父类对应版本的构造函数。
当实例化一个子类时,先执行父类中的构造函数,再执行子类中自有的构造函数。
类的 构造函数 和 析构函数 是不能被继承的。
子类和父类有相同的方法,实例化时,先调用子类的方法,如果子类的方法不存在了,就调用它继承的父类的方法。
新闻阅读器的两种格式:RSS 和 Atom
1. Atom 格式的Feed 文件:feed 层 和 entry层。
2. RSS 格式的Feed文件:rss 层、channel层 和 item 层。
继承模拟了现实世界的关系,继承实现了代码的重用,
继承使得程序结构清晰,子类和父类的层次结构清晰,
最终目的:使子类只关注子类的相关行为和状态,无须关注父类的行为与状态。
第 7 章 : 用对象思考:多态
多态:两个或多个属性不同类的对象,对于同一个消息(方法调用)作出不同响应的方式。
也可以说是同一个类在不同场合下表现出不同的行为特征。可以让我们不用关心某个
对象到底是什么具体类型,就可以使用该对象的某些方法。
抽象方法:是一个没有实现的方法,通过在定义方法时增加关键字abstract 可以声明抽象方法。
语法:访问修饰符 abstract 返回类型 方法();
抽象类:含有抽象方法的类必然时抽象类。
语法:访问修饰符 abstract class 类名
注意:1.抽象类不能被实例化。
2.抽象类不能是密封或者静态的。
3.抽象类必须在其非抽象的子类中实现抽象方法。
抽象类中的方法并不一定都是抽象方法,抽象类也可以容纳有具体实现的方法,或者称为具体方法。
含有抽象方法的类必然是抽象类。
重写抽象方法:当从一个抽象基类派生出一个子类时,子类将继承基类的所有特征,包括它的未实现的抽象方法。
抽象方法必须在其子类中实现,除非它的子类也是抽象类。
在子类中实现一个抽象方法的方式是使用override关键字来重写抽象方法。
语法:访问修饰符 override 返回类型 方法()
抽象类和抽象方法的应用场合:由于抽象父类中提供的抽象方法,要在子类中实现。
(父类提供了一个功能或者规定,约束子类的行为)
is 操作符的使用:用于检查对象是否与给定的类型相同。例如:判断一个objects是否是字符串型。
as 操作符的使用:用于两个对象之间的类型转换。
当转换失败时,运算符将产生空,而不是引发异常。
虚方法:用virtual关键字修饰,可以有方法体。
在父类中定义虚方法,然后在子类中可以重写虚方法,也实现了面向对象的多态。
语法:访问修饰符 virtual 返回类型 方法(){ //方法体 }
抽象方法和虚方法都可以重写,都可以实现多态性。
抽象方法和虚方法区别:
虚方法 | 抽象方法 |
用 virtual 修饰 | 用 abstract 修饰 |
要有方法体,哪怕是一个分号 | 不允许有方法体 |
可以被子类override | 必须被子类override |
除了密封类外都可以写 | 只能在抽象类中 |
简单工厂模式:是设计模式中的一种,是一种经验的总结。
好处:1.提高代码的复用性。2.更易于扩展。3.更容易适应需求的变化。
简单工厂模式用于在调用者不知道对象属于哪个子类的情况下,创建不同的对象。
第 8 章 : 用对象思考:接口
接口:是一组规范,遵守这个规范和标准就能实现某种功能。(接口是特殊类)
在.NET中,接口同样是一种规范和标准,它可以约束类的行为。(接口的关键字:interface)。
IComparable是一个接口,在这个接口中有一个没有实现的方法CompareTo(object obj)
语法:public interface IComparable { int CompareTo (Object obj); }
这个接口中的方法用于将当前实例与另一个对象比较大小一个类如果实现了这个接口中的CompareTo方法,
意味着这个类的对象是可比较的,它返回一个整型的返回值,返回的含义如下:
如果返回值小于0,则当前实例小于obj。
如果返回值大于0,则当前实例大于obj。
如果返回值等于0,则当前实例等于obj。
1. 接口中可以包含事件、属性、方法、索引器等,但是都不能够实现,它们都是抽象的。
接口中的方法:public interface ISampleInterface{ void ShowName(); }
接口中的属性:public interface ISampleInterface{ string Name { get; set; } }
2. 定义一个接口的名称通常都是以 “I”开头。
3. 我们习惯的说法是实现了一个接口、继承了一个类。
4. 实现一个接口的语法与继承类似:class Student:IComparable。
5. 如果类已经继承了一个父类,则以“ ,”分隔父类和接口。
如:public class Student:Person ,IComparable (Student 是子类 , Person是父类 , IComparable 是接口)。
6. 一个圆圈表示该类是实现了一个接口。
接口小结:
1. 接口是对继承单根性的扩展:在C#中,一个类虽然不能实现多重继承,但是一个类可以实现多个接口。
通过实现多个接口可以说是变相地实现了类的多重继承。
2. 接口是一种规范和标准:一个类如果实现了一个接口,意味着这个类遵循了某中规范和约定。
其他类可以通过这些规范和约定与它通信。
3. 接口屏蔽了实现的细节:一个类如果实现了IComparable 接口,便可以让这个类的对象进行排序。
4. 接口的使用方便团队协作开发。
抽象类 与 接口 的区别:
| 抽 象 类 | 接 口 |
不同点 | 用 abstract 定义 | 用 interface 定义 |
只能继承一个类 | 可以实现多个接口 | |
非抽象派生类必须实现抽象方法 | 实现接口的类必须实现所有成员 | |
需要override 实现抽象方法 | 直接实现 | |
相似点 | 不能被实例化 | |
包含未实现的方法 | ||
派生类必须实现未实现的方法 |
IComparable<T>是IComparable接口 的泛型版,它对类型的约束更严格。
IComparer<T>通常称为比较器,它用于比较两个对象的大小,可以作为参数传递给Sort()方法进行排序。
接口作为参数就是要传递一个实现了这个接口的对象。接口作为返回值就是要返回一个实现了这个接口的对象。
抽象方法通过其子类使用override关键字重写实现,接口由实现它的类直接实现。
抽象类只需子类实现它的抽象方法,接口必须实现所有成员。
Sort()方法的重载:public void Sort(IComparer<T> comparer)
这个重载的方法的参数是IComparer<T>泛型接口,又称比较器,如果将不同的比较器传入Sort()方法
就可以实现不同的比较方式。
第 9 章 : 序列化与反射
序列化:将对象的状态存储到特定存储介质中的过程。
语法:public void Serialize(Stream serializationStream,Object graph)
(serializationStream 是指定程序化过程的文件流。 graph 是保存的对象)
序列化的目的:1. 作为配置文件保存。
2. 用于从一个应用程序向另一个应用程序传递。
3. 作为网络应用传递。
序列化方式: 1. 二进制
2. Soap:不支持泛型集合,但支持集合。
3. Xml:不能对私有内容、只读属性、方法、索引器 序列化。
特性:附加的说明。
特性分类:1.预定义的特性。2.自定义的特性(Attribute)
应用程序:(.exe 和 .dell)
1.应用程序域。2.反问修饰符。3.模块。4.类型。5.属性、方法。
反序列化:将存储介质中的数据重新构建为对象的过程。
语法:public Object Deserialize (Stream serializationStream)
程序集:描述它的程序集清单.类型元数据.MSIL代码和资源组成,这些部分都分布在一个文件中,或者几个文件中。
每一个程序集都包含描述该程序集中各元素彼此如何关联的数据集合。程序集清单包含这些程序集的元素据。
程序集清单:包含指定该程序集的版本要求 和 安全标识所需的所有元数据。
程序集清单的内容:
信 息 | 说 明 |
程序集名称 | 指定程序集名称的文本字符串 |
版本号 | 主版本号和次版本号,以及修订号和内部版本号 |
区域号 | 有关该程序集支持的区域性或语言的信息 |
强名称信息 | 如果已经为程序集提供了一个强名称,则为来自发行者的公钥 |
程序集中所有的列表 | 构成该程序集的文件 |
类型引用信息 | 控制对该程序集的类型和资源的引用如何映射到包含其声明和实现的文件中 |
有关被引用程序集的信息 | 该信息用于从程序集导出的类型 |
程序集清单的主要功能:
1. 列举构成该程序集的文件。
2. 控制对该程序集的类型和资源的引用如何映射到包含其声明和实现的文件中。
3. 列举该程序集所依赖的其他程序集。
4. 在程序集的使用者和程序集的实现详细信息的使用者之间提供一定程度的间接性。
5. 呈现程序集自述。
元数据:是一种二进制信息,它以非特定语言的方式描述在代码中定义的每一个类型和成员,
程序集清单也是元数据的一部分。
元数据主要存储的信息:
1. 程序集的说明。
2. 标识(名称、版本、区域性、公钥)。
3. 导出的类型。
4. 该程序集所依赖的其他程序集。
5. 运行所需的安全权限。
类型元数据 包含:1. 类型的说明。
2. 名称、可见性、基类和实现的接口。
3. 成员(方法、字段、属性、事件、嵌套的类型)。
4. 属性。
5. 修饰类型和成员的其他说明性元素。
程序集属性列表:
属 性 | 说 明 |
AssemblyCompany | 指定公司名 |
AssemblyTitle | 程序集的描述性名称 |
AssemblyDescription | 描述程序集或产品 |
AssemblyConfiguration | 指定建立信息,例如零售或者调试信息 |
AssemblyProduct | 指定程序集所属产品的名称 |
AssemblyCopyright | 包含版权和商标信息 |
AssemblyVersion | 程序集的版本号 |
5种访问修饰符:
(权限等级) | 类内部 | 同一程序集的 派生类 | 同一程序集的 其他类 | 不同程序集的 派生类 | 不同程序集的 其他类 |
Private(1 最严) | 可以 | 不可以 | 不可以 | 不可以 | 不可以 |
Protected (2) | 可以 | 可以 | 不可以 | 可以 | 不可以 |
Internal (4) | 可以 | 可以 | 可以 | 不可以 | 不可以 |
Public (5) | 可以 | 可以 | 可以 | 可以 | 可以 |
Protected internal(3) | 可以 | 可以 | 可以 | 可以 | 不可以 |
反射:用于在运输时通过编程方式获得类型信息。(动态获得程序集或类的信息)