深入.NET平台和C#编程 知识点整理
北大青鸟
目录
第一章 深入.NET框架
一、.NET结构
二、CLR的两个组成部分
CTS
称为为通用类型系统
定义了在IL中的数据类型
CLS
称为公共语言规范
包括集中面向对象的编程语言的通用功能
三、核心类库及命名空间
核心类库说明 | 命名空间 |
使用泛型 | System.Collections.Generic |
对文件的基本操作 | System.IO |
对网络协议进行编程 | System.net |
对数据库的访问 | System.Data |
开发Windows应用程序 | System.Windows.Forms |
对GDI+基本图形的操作 | System.Drawing |
四、封装
是面向对象的三大特征之一
一个不可分割的独立实体
隐藏内部的细节
保留对外接口
通过访问修饰符授权
封装·类
保证数据的安全性
提供清晰的对外接口
类的内部实现可以任意修改 ,不影响其他类
五、类的属性
private string _name; //姓名public string Name
{
get { return _name; }
set { _name = value; }
}
可简化为:
public string Name { get; set; }
六、总结
第二章 深入 C# 数据类型
一、常用数据类型
数据类型按存储方式可分为两类:值类型和引用类型
常用数据类型 | Java | C# | 举例 |
整型 | int | int | 年龄 |
浮点型 | float | float | 成绩 |
双精度型 | double | double | 圆周率 |
布尔型 | boolean | bool | 是否少数民族 |
枚举类型 | enum | enum | 颜色 |
字符串 | String | string | 家庭住址 |
二、结构
访问修饰符 struct 结构名
{
定义结构成员
}
当对象需要用较少的字段来表示时,可以选用结构
结构是值类型,数据提取速度快
但是频繁的赋值操作会占用较大空间, 在开发中多数情况下都定义为类!!!
三、数据类型
| 值类型 | 引用类型 | ||
源自 | System.ValueType | System.Object | ||
存储方式 | 存储值 | 存储对象引用 | ||
常用类型 | 基本数据类型 | 整型:int | 类 | 基类:System.Object |
长整型:long | ||||
浮点型:float、double | ||||
| ||||
字符型:char | 自定义类:class | |||
布尔型:bool | ||||
枚举类型(enum) | 接口 | |||
结构类型(struct) | 数组 |
四、引用类型和值类型
引用类型的赋值不是内容复制,是把地址复制
值方式传递引用类型参数
参数在方法中被修改
值方式传递值类型参数
不会被修改
值传递+值类型 不变
值传递+引用类型 变
引用传递ref+值类型 变
引用传递ref+引用类型 变
不同类型参数传递 | 参数变化是否保留 |
值方式传递值类型 | 否 |
值方式传递引用类型 | 是 |
引用方式(ref)传递值类型 | 是 |
引用方式(ref)传递引用类型 | 是 |
五、封装的特点:
1.结构可带有方法、字段、索引、属性、运算符方法和事件。
2.结构可定义构造函数,但不能定义析构函数。但是,您不能为结构定义无参构造函数。无参构造函数(默认)是自动定义的,且不能被改变。
3.与类不同,结构不能继承其他的结构或类。
4.结构不能作为其他结构或类的基础结构。
5.结构可实现一个或多个接口。
6.结构成员不能指定为 abstract、virtual 或 protected。
7.当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
8.如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。
六、总结
第三章 使用集合组织相关数据
一、 ArrayList是一个可动态维护长度的集合
(1)如何实现:
1、引入System.Collections命名空间
2.实例化ArrayList对象
(2)添加元素:
用Add添加 添加一个对象到集合的末尾 返回索引
向ArrayList中添加值类型的元素时会执行装箱处理
(3)访问ArrayList中的单个元素
(类型) ArrayList [index] //按指定索引(下标)取得对象
需要类型转换
(4)ArrayList的遍历
1.使用和数组类型的方式(通过索引)
for (int i = 0; i < engineers.Count; i++)
{
SE seFor = (SE)engineers[i];
Console.WriteLine(seFor.Name);
}
2.使用foreach方式 (通过对象)
foreach (Object obj in engineers)
{
SE seForeach = (SE)obj;
Console.WriteLine(seForeach.Name);
}
(5)删除ArrayList的元素
删除一个元素 剩余的元素会自动调整索引
(6)常见错误:
未引入命名空间
定义是未实例化
2、通过Hashtable获取对象
(1)定义 特点
(2)给Hashtable添加元素
.Add(Key,Value);
(3)获取Hashtable的元素
类型 名=(类型)Hashtable[“key”]; //通过key获取元素
(4)删除Hashtable的元素
Hashtable.Remove(“key”); //通过Key删除元素
(5)如何遍历Hashtable
不能遍历整个对象,而是遍历Values
foreach(Object obj in engineers.Values)
{
SE se = (SE)obj;
Console.WriteLine(se.Name);
}
可以遍历Keys
foreach (Object obj in engineers.Keys)
{
Console.WriteLine((string)obj);
}
可以遍历键值对
foreach (DictionaryEntry en in engineers)
{
Console.WriteLine((string)obj);
Console.WriteLine(((SE)en.value).Name);
}
(6)使用集合存储时容易出现的问题
三、List<T>(泛型集合)
(1)什么是泛型集合
泛型<T>是最常见的用途是创建集合类
泛型集合可以约束集合内的元素类型
典型泛型集合List<T>、DIctionary<K,V>
(2)使用步骤
1.命名空间:System.Collections.Generic
2.创建List<T>泛型集合
3.遍历无序类转换
foreach (SE se in engineers)
{
MessageBox.Show(se.SayHi());
}
(3)List<T> 与 ArrayList 对比
异同点 | List<T> | ArrayList |
不同点 | 增加元素时类型严格检查 | 可以增加任何类型 |
添加和读取值类型元素时,无需装箱拆箱 | 添加和读取值类型元素时,需要装箱拆箱 | |
相同点 | 通过索引访问集合的元素 | |
添加对象方法相同 | ||
通过索引删除元素 |
四、Dictionary<K,V>
(1)定义
Dictionary<K,V>通常称为字典
<K,V>约束集合中元素类型
编译时检查类型约束
无需装箱拆箱操作
(2)如何new
Dictionary<Key,Value> dic = new Dictionary<Key,Valu>();
(3)添加
dic.Add(Key,Value);
(4)通过key获取元素
value ee=div[key];
(5)通过Key删除元素
dic.Remove(Key);
(6)遍历
//Dictionary<string, SE> 方式
foreach (SE se in engineers.Values)
{
MessageBox.Show(se.SayHi());
}
(7)Dictionary<K,V>与Hashtable
异同点 | Dictionary<K,V> | Hashtable |
不同点 | 增加元素时类型严格检查 | 可以增加任何类型 |
无需装箱拆箱 | 需要装箱拆箱 | |
相同点 | 通过Key获取Value | |
添加对象方法相同 | ||
遍历方法相同 |
五、泛型的重要性
1.代码重用,未来的主流技术
2.性能高,避免繁琐的装箱拆箱
3.提供了更好的类型安全性
4.CLR支持泛型
六、总结
第四章 深入类的方法
一、构造函数
(1)作用 初始化变量
(2)特点(老郑)
(3)参数
(4)注意
二、方法重载
(1)什么是方法重载
(2)最经典的举例
第五章 体检套餐管理系统
(1)关键代码
第六章 初识继承和多态
一、继承
(1)概述
在C#中,类可以继承自另一个类
衍生的类(子类)继承父类的方法和数据成员
子类继承父类,父类派生子类
父类又叫基类
子类又叫派生类
class 子类:父类
{...... }
(2)如何实现继承
(3)base调用父类成员
public SE(string id,string name,int age, Gender gender, int popularity)//线束调用父类的构造函数
: base(id, age, name, gender)
{
this.Popularity = popularity;//公共属性在父类构造函数中初始化,代码简洁、冗余少
}
2、访问修饰符
public 公共的,谁都可以
private 私有的,只有自己可以
protected 受保护的,自己和子类可以
internal 只有在同一个程序集的文件中,内部类型或者是成员才可以访问
| 类内部 | 子类 | 其他类 |
public | 可以 | 可以 | 可以 |
private | 可以 | 不可以 | 不可以 |
protected | 可以 | 可以 | 不可以 |
(5) is a的应用
三、方法重写
(1)在父类里的方法
public virtual string SayHi()//用virtual关键词修饰
{
string message = string.Format("大家好!");
return message;
}
虚方法
访问修饰符 virtual 返回值类型 方法名()
{
//方法体
}
(2)在子类的方法(重写父类方法)
public override string SayHi() {……} //用override关键字修饰
方法重写
访问修饰符 override 返回值类型 方法名()
{
//方法体
}
(3)注意
父类中定义的虚方法并非必须被子类重写。在父类中可给出虚方法的默认实现。如果子类不重写父类的虚方法,依然执行父类的默认实现;反之,则执行子类重写后的方法
四、多态
(1)什么是多态
第七章 深入理解多态
一、里氏替换原则(LSP)
二、操作符:is 与 as操作符
(1)is:
if (empls[i] is SE) {} //判断empls集合的元素是否是SE对象
(2)as:
for (int i = 0; i < empls.Count;i++ )
{
if (empls[i] is SE)
{
SE se = empls[i] as SE; //一种类型转换方式,讲empls集合的元素转化成SE对象 转换失败返回null;
Console.WriteLine(se.SayHi());
}
}
三、抽象方法与抽象类
(1)什么是抽象方法
[访问修饰符] abstract class 类名{ [访问修饰符] abstract 返回类型 方法名();}
(2)如何实现
(3)对比虚方法
抽象方法 | 虚方法 |
用 abstract 修饰 | 用 virtual 修饰 |
不允许有方法体 | 要有方法体,哪怕是一个分号 |
必须被子类 override | 可以被子类 override |
只能在抽象类中 | 除了密封类都可以写 |
四、面向对象的三大特性
封装
继承
多态
第八章 可扩展标记语言XML
一、XML可扩展标记语言
(1)解析XML文件
XmlDocument myXml = new XmlDocument(); //用于解析XML文件的类
myXml.Load("Engineer.xml"); //加载制定的XML数据
XmlNode engineer = myXml.DocumentElement; //获取根节点
foreach (XmlNode node in engineer.ChildNodes ) //获取当前节点的所有子节点
{
switch (node.Name) //当前节点名字
{
case "Name":
Console.WriteLine("姓名:{0}",node.InnerText);//当前节点的值
break;
//…
}
}
XmlDocument对象表示XML整个文档
XmlNode对象表示XML文件的单个节点
对象 | 属性和方法 | 说明 |
XmlDocument | DocumentElement 属性 | 获取文档的根 |
ChildNodes 属性 | 获取节点的所有子节点 | |
void Load()方法 | 加载整个XML的结构 | |
XmlNode | InnerText 属性 | 当前节点的值 |
Name属性 | 当前节点的名字 | |
ChildNodes 属性 | 当前节点的所有子节点 |
(2)TreeView的使用
1.TreeView空间重要属性和事件
2.节点对象的属性
属性 | 说明 |
Text | 节点显示的文本 |
Index | 节点在所在集合中的索引 |
Parent | 节点的父节点(TreeNode) |
Level | 节点在树形菜单中的层级0、1….. |
Tag | 节点值 |
Nodes | 节点的所有下一级子节点 |
3.为TreeView空间添加根节点
TreeNode rootNode = new TreeNode("音乐频道");
this.tvMenu.Nodes.Add(rootNode);
为某个选择子节点添加子节点
this.tvMenu.SelectedNode.Nodes.Add(node);
4.TreeView删除节点
this.tvMenu.SelectedNode.Remove();
5.清空节点
this.tvMenu.SelectedNode.Nodes.Clear();//经常用在刷新TreeView显示前
this.tvMenu.Nodes.Clear(); //清空TreeView控件中所有节点
// 树状菜单的清空方法常用在更新树状菜单方法的最前面,这样可以保证节点不被重复加载
第九章 文件操作
一、文件读写
(1)步骤
(2)创建文件流
FileStream myfs = new FileStream( string path, FileMode mode );
//path制定文件路径
//mode如何打开文件
FileMode枚举
Create:创建一个新文件。如果文件存在,则改写旧文件
Open:指定打开现有文件。指定的文件必须存在,否则会发生异常
CreateNew:新建一个文件。如果文件存在会发生异常,提示文件已经存在
Append:打开现有文件追加
转义符:
string path ="D:\\Text.txt";
string path =@"D:\Text.txt";
(3)创建写入器和读取器
文本文件写入器:SteamWriter
StreamWriter mySw = new StreamWriter(myfs);//传入文件流
mySw.Write(content);//写入方法
mySw.WriteLine(content);//写入一行数据的方法
文件文本读取器
StreamReader mySr = new StreamReader(myfs);//传入文件流
content = mySr.ReadToEnd();//读取到文件末尾
content = mySr.ReadLine();//读取一行
(4)将数据写入文本文件
FileStream myfs = new FileStream(path, FileMode.Create);//创建一个文件流
StreamWriter mySw = new StreamWriter(myfs);//创建写入器
mySw.Write(content);//写入操作
mySw.Close();//关流
myfs.Close();//关器
如果一个程序用了多个流、读写器,它们的关闭顺序一般要和自身在程序中被创建的顺序相反
(5)读取文本文件
使用OpenFileDialog控件显示打开文件的窗口
this.ofdMain.ShowDialog();
string path = ofdMain.FileName; //选择文件
string content;
//……
FileStream myfs = new FileStream(path, FileMode.Open);//创建一个文件流
StreamReader mySr = new StreamReader(myfs);//创建读取器
content = mySr.ReadToEnd();//讲流从当前的位置堵到末尾
txtContent.Text = content;
mySr.Close();//关闭
myfs.Close();
解决读取时的中文乱码
FileStream myfs = new FileStream(path, FileMode.Open);
//读取器
StreamReader mySr = new StreamReader(myfs, Encoding.Default);//默认使用Unicode字符, 设置Encoding改变默认设置
content = mySr.ReadToEnd(); //Encoding.UTF8或Encoding.Default或Encoding.GetEncoding("XXX")
txtContent.Text = content;
//……
Encoding.UTF8或
Encoding.Default或
Encoding.GetEncoding("XXX")
(6)文件操作
File类:提供操作文件的各种方法
方法 | 说明 |
bool Exists(string path) | 用于检查指定文件是否存在,该方法返回一个布尔值 |
void Copy(string sourceFileName, string destFileName) | 将指定路径的源文件中的内容复制到目标文件中,如果目标文件不存在,则在指定路径中新建一个文件 |
void Move (string sourceFileName, string destFileName) | 将指定文件移动到一个新的路径 |
void Delete(string path) | 删除指定的文件,如果指定的文件不存在,则不引发异常 |
操作实例
//检查一个文件是否存在
if (!File.Exists(this.txtFileName.Text))
{
MessageBox.Show("文件不存在");
}
else
{
//将源文件复制到一个新文件
File.Copy(this.txtFileName.Text, this.txtCopyName.Text);
MessageBox.Show("复制成功!");
}
Directory 类提供对文件夹的移动、删除等操作
方法 | 说明 |
bool Exists(string path) | 用于检查指定文件夹在磁盘上是否存在 |
void Move(string | 用于将文件或目录及其内容移到新位置 |
sourceDirName, | |
string destDirName) | |
void Delete(string path, | 删除指定目录,如果bool指定true,则删除子目录中的所有目录内容 |
bool recursive) | |
void Delete(string path) | 从指定路径删除空目录 |
(7)File类与Directory类
//静态
public static class File
public static class Directory
静态类 | 非静态类 |
用static修饰 | 不用static修饰 |
只包含静态成员 | 可以包含静态成员 |
不可以包含实例成员 | 可以包含实例成员 |
使用类名调用静态成员 | 使用实例对象调用非静态成员 |
不能被实例化 | 可以被实例化 |
不能包含实例构造函数 | 包含实例构造函数 |
(8)静态成员
1.使用staic修饰符
静态成员为一个类的所有实体所共享,它属于类,而不属于类的某个对象!例如:太阳
静态成员方法,提供独立于 特定对象之外的普遍功能
class 类名
{
public static 数据类型 变量名;
public static 返回值类型 方法名(参数列表)
{
//方法体;
}
}
2. 静态成员的使用
类名.变量名 = XX; //给变量赋值
类名.方法名(); //调用静态方法
3. 静态成员与实例成员
静态方法 | 实例方法 |
static关键字 | 不需要static关键字 |
使用类名调用 | 使用实例对象调用 |
可以访问静态成员 | 可以访问静态成员 |
不可以直接访问实例成员 | 可以直接访问实例成员 |
调用前初始化 | 实例化对象时初始化 |
提供实例方法的文件类
FrileInfo类
属性/方法 | 说明 |
Exists | 用于检查指定文件是否存在,返回一个布尔值 |
Extension | 获取表示文件扩展名部分的字符串 |
Name | 获取文件名 |
FullName | 获取目录或文件的完整目录 |
FileInfo CopyTo(string) | 将现有文件复制到新文件,不允许覆盖现有文件 |
void Delete() | 永久删除文件 |
void MoveTo(string) | 将指定文件移到新位置 |
由于File类的静态方法在使用时都会进行安全检查,所以如果想要多次使用某个文件对象,可以考虑使用FileInfo类相应的实例方法,因为并不总是需要安全检查
DirectoryInfo类
方法 | 说明 |
DirectoryInfo[ ] GetDirectories() | 返回当前目录的子目录对象数组 |
FileInfo[ ] GetFiles() | 返回当前目录下文件列表(FileInfo对象数组) |
如果打算多次重用某个目录对象,可以考虑使用DirectoryInfo类的实例方法
第十一章 影院售票系统