第一章 深入.NET框架
1.1 Microsoft .NET框架概述
.NET框架的优势
* 提供了一个面向对象的编程环境,完全支持面向对象编程,.NET 框架提高了软件的可复用性,可扩展性,可维护性和灵活性
* 对Web应用的强大支持
* 对Web Service(Web服务)的支持,Web Service是.NET非常重要的内容,它可以实现不同应用程序之间相互通信
* 实现SOA,支持云计算,同时,.NET 也提供了对云计算的支持,Windows Azure 就是一个构建在微软数据中心提供云计算的应用平台。
* 支持构建 .NET 程序的炫彩外衣。
1.2 .NET 框架体系结构
.NET 框架运行在操作系统之上,是 .NET 最基础的框架,它提供了创建,部署和运行 .NET 应用的环境,主要包含
公共语言运行时(CLR)和框架类库(.NET Framework 库类,FCL),并且支持多种开发语言
.NET 框架具有两个主要组件:CLR和FCL。
CLR 是.NET 框架的基础。
FCL 是一个综合性的面向对象的可重用类型集合。
.NET框架的组成
FCL (Framework Class Library) 框架类库
CLR(Common Language Runtime) 公共语言运行时
CLR的两部分
CLS(公共语言规范) Common Language Specification
CTS:(通用类型系统) Common Type System
1.3 CLR
CLR的全称为公共语言运行时,它是所有.NET 应用程序运行时环境,是所有.NET 应用程序都要使用的编程基础
它如同一个支持 .NET应用程序运行和开发的虚拟机。
CLR 包含两个组成部分:CLS(公共语言规范)和CTS(通用类型系统)
常见类库
类库:一堆类的集合。
*System:此命名空间包含所有其他的命名空间
6个常用的命名空间
*System.Collections.Generic: 泛型
*System.IO: 文件操作
*System.Net: 网络编程
*System.Data: 提供对表示ADD.NET 结构的类的访问(数据库)
*System.Windows.Forms: Winform窗体
*System.Drawing: GDI+技术
2.1 面向对象
1.类和对象
类和对象有着本质区别,类定义了一组概念的模型,面向对象是真实的实体,关系如下;
*由对象归纳为类,是归纳对象共性的过程
*在类的基础上,将状态和行为实体化为对象的过程称为实例化
对于类的属性,通过get 和set 访问器进行访问和设置,用来保障类中数据的安全,属性访问器分为以下3种:
*只写属性:只包含set访问器
*只读属性:只包含get访问器
*读写属性:同时包含set访问器和get访问器
2. 封装
封装的好处
*保障数据的安全性
*提供清晰的对外接口
*类内部实现可以任意修改,不影响其他表
将字段封装为属性是封装的一种方式,类的私有方法也是一种封装;
3.字段和属性区别?
解析:01.属性不能保存数据,真正保存数据的是字段
02.属性是可有可无的,字段是必须的。
03.如果字段只想让类内部访问,那么设置成private,如果想找一个中间者,
在Main方法中访问到Student类中的私有字段,那么属性可以是一种选择,字段和属性成对出现。
属性无非就是有get和set两个访问器组成
get:取值
set:赋值
9.自动属性
自动属性应用场景:当我们不需要做逻辑判定的时候可以使用自动属性
第二章 深入C#数据类型
1. 对象数组
任何对象都会自动调用它的ToString()方法,而程序员自定义类,默认父类都是Object,即使类中没有任何内容,也可以复用父类的ToString()。
父类的ToString()的底层实现刚好就是获取当前对象所属命名空间+类名。
2. 结构
1.结构体是值类型
2.结构体中可以有属性和方法
3.用法和类没有区别
4.结构体可以不用new,直接使用属性和方法
5、在结构体中不能给字段赋初值,但是类中可以
6、结构体中没有默认构造函数,但类中有默认构造函数
构造:方法名和类名相同
没有返回值,连void都不能有,完成对成员变量初始化工作。
2.1 结构的定义
访问修饰符 struct 结构名
{
//结构体
}
示例
public struct Student
{
public int id; //ID
public int age ; //年龄
public void Show()
{
Console.WriteLine("ID:{0} 年龄:{1}",id,age);
}
}
//调用
static void Main(string[] args)
{
Student stu; //创建学生构造
stu.id=1001; //给学生赋值
stu.age=20; //给年龄赋值
stu.Show();
}
3.构造函数
默认如果定义了一个类,系统会自动的生成一个和该类名称相同,并且没有返回值类型,甚至连Void都没有的方法,该方法就称为构造函数!
Student stu=new Student();
注意问题:值类型的直接父类都是ValueType,而ValueType又继承自Object
特殊的值类型:枚举和结构体
特殊的引用类型:数组和接口
4.装箱和拆箱
将值类型转换为引用类型的过程称为装箱,反之称为拆箱
由于装箱和拆箱对系统性能损耗很大,所以在真实的开发中我们尽量避免装箱和拆箱的操作。
Object:是引用类型,并且是所有数据类型(值类型,引用类型)的父类
static void Main(string[] args)
{
int i=123;
object o=i; //装箱
int j=(int) o; //拆箱
}
面试题:
int number=3; 值类型的直接父类:ValueType,ValueType的父亲是Object
Console.WriteLine(number.ToString());
结论:没有装箱
//ToString() Object提供的,所以没有装箱。
下去自己查!Why ??
老师:什么时候应该装箱,什么时候应该拆箱?
解析:由于装箱和拆箱过程都要损耗系统的性能,所以在开发中应该尽量避免装箱和拆箱。
5. 值类型传递和引用类型传递
注意:值传递和引用传递判定依据是有没有ref关键字
结论:
01.如果方法的参数类型本身就是引用类型,那么对参数值的修改会永久保存
例如:public void TP(SE se)
{
se.Count++;//真正的修改se对象的Count值
}
02.如果方法的参数类型本身是值类型,又没有ref修饰,那么对参数值的修改,不会永久保存()
03.如果方法的参数类型本身是值类型,但是有ref修饰,那么对象参数值的修改,也会永久保存。
值类型传递 :不带ref的参数传递 SE se
引用类型传递:带ref的参数传递
Windows Live Writer
第三章 使用集合组织相关数据
一,集合
1,ArrayList
ArrayList可以动态维护,ArrayList的容量可以根据需求自动扩充,他的索引会根据程序的扩展重新进行分配和调整
由于给ArrayList添加的元素都会被转换为Object型,所以访问这些元素的时候必须把他们转换回原来的类型。
2. Hashtable
Hashtable 的数据是通过键(Key)和值(Value)来组织,Hashtable也属于System.Collections命名空间,他的每个元素都是一个键/值对。
二,泛型和泛型集合
1,泛型集合List<T>
语法:
List<T> 对象名=new List<T>();
“<T>”中的T可以对集合中的元素类型进行约束,T表明集合中管理的元素类型
示例:
//建立工程师员工集合
List<SE> list=new List<SE>();
//初始化三个工程师员工
SE jack=new SE();
//属性赋值
jack.ID="001";
jack.Name="张三";
SE joe=new SE();
//赋值省略。。。
//将元素添加到集合中
list.Add(jack);
list.Add(joe);
示例:
//通过索引访问
SE se=list[0];
//通过索引或者对象删除
list.RemoveAt(0);
list.Remove(joe);
//遍历
foreach(SE sein list)
{
//遍历时无需类型转换
MessageBox.Show(se.SayHi());
}
2,泛型集合Dictionary<K,V>
语法:
Dictionary<K,V> 对象名=new Dictionary<K,V>();
说明:<K,V>中的K表示集合中Key的类型,V表示Value的类型
示例:
//建立工程师员工集合
Dictionary<string,SE> list=new Dictionary<string,SE>();
//初始化三个工程师员工
SE jack=new SE();
//属性赋值
jack.ID="001";
jack.Name="张三";
SE joe=new SE();
//属性赋值省略
//添加元素
list.Add(jack.ID,jack);
list.Add(joe.ID,ema);
//打印集合中元素数目
MessageBox.Show(string.Format("部门共包括{0}个工程师。",list.Count.ToString()));
//通过Key访问元素
SE se=list["001"];
//通过key删除元素
list.Remove("001");
//遍历
foreach(SE se in list.Values)
{
//遍历时无需类型转换
MessageBox.Show(se.SayHi());
}
第四章 深入类的方法
1,构造函数
*方法名与类名相同
*没有返回值类型
*主要完成对象的初始化工作
语法:(无参构造函数)
访问修饰符 类名()
{
//方法体
}
示例:
public class SE
{
//无参构造函数:设置属性初始值
public SE()
{
this.ID="000";
this.Age=20;
this.Name="张三";
this.Gender=Gender.male;
}
}
语法:(带参构造函数)
访问修饰符 类名(参数列表)
{
//方法体
}
2,方法重载
特点:
*方法名相同
*方法参数类型不同或者参数个数不同
*在同一个类中
3.对象交互
在面向对象的程序中,对象通过公开方法和属性完成与其他对象的交互,可以认为方法的参数及
方法的返回值都是对象间相互传递的消息
第六章 初识继承和多态
1,继承
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或者
新的功能,也可以用已存在的类的功能
C#可以用base关键字调用父类的构造函数,只要在子类的构造函数后添加“:base(参数列表)”
就可以指定该子类的构造函数调用父类的那个构造函数了,这样便可以实现继承属性的初始化,然后
在子类本身的构造函数中完成对子类特有属性的初始化即可。
//Emp类的构造函数
public Emp(string id,int age,stirng name,Gender gender)
{
this.ID=id;
this.Age=age;
this.Name=name;
this.Gender=gender;
}
//SE类的构造函数
public SE(string id,stirng name,int age,Gender gender,int popularity):
base(id,age,name,gender)
{
//继承自父类 的属性
//调用父类的构造函数可以替换掉的代码
// this.ID=id;
//this.Age=age;
//this.Name=name;
//this.Gender=gender;
//SE类的扩展属性
this.Popularity=popularity;
}
2.多态
语法:
访问修饰符 virtual 返回类型 方法名()
{
//方法体
}
在子类中这样定义
public override string SayHi()
{
//方法体
}
实现多态
1,实现方法重写
*父类中定义SayHi()方法,用virtual关键字定义为虚方法
*在子类中定义子类自己的SayHi()方法,用override关键字修饰,就实现了父类的SayHi()方法的重写;
2,定义父类变量,用子类对象初始化父类变量
第七章 深入理解多态
1,里氏替换原则
里氏替换原则是软件设计应该遵守的重要原则之一,有了里氏替换原则,才使继承复用称为可能,只有当子类可以替换掉父类时,
软件的功能不受影响,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。
2,is 和 as 操作符的使用
is 操作符用于检查对象和指定的类型是否兼容
as 操作符主要用于两个对象之间的类型转换
一,抽象类和抽象方法
*抽象方法是一个没有实现的方法,通过定义方法时增加关键字abstract可以声明抽象方法
*不能被实例化
*抽象类不能new对象
*抽象类不能是静态类或密封类
*抽象方法不能有方法体,而且抽象方法只能在抽象类中
*抽象方法就是为了约束子类中方法存在的形式(参数列表和返回值类型)
*抽象类中的所有抽象方法必须被子类重写,除非子类也是抽象类
二,面向对象的三大特性
*封装:保证对象自身数据的完整性和安全性
*继承:建立类之间的关系,实现代码复用,方便系统的扩展
*多态:相同的方法调用可实现不同的实现方式
第八章 可扩展标记语言XML
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> </configuration>
*XML中的每对标记通常被称为节点,它们必须是成对出现的
*XML中用于描述数据的各个节点可以自由扩展
*XML文件中的节点区分大小写
二,解析XML
static void Main(string[] args) { //读取Xml文件方式 #region 方式一 XmlDocument doc = new XmlDocument(); //绑定文件 doc.Load("Books.xml"); //将整篇文档中的根节点玲出来 XmlNode root = doc.DocumentElement; //根据root,找所有子节点的集合 root.ChildNodes foreach (XmlNode item in root.ChildNodes) { //一个item就是一个book foreach (XmlNode child in item.ChildNodes) { //一个child代表一本书的单个属性 switch (child.Name) { case "name": Console.Write(child.InnerText); break; case "age": Console.Write(child.InnerText); break; case "sex": Console.WriteLine(child.InnerText); break; default: break; } } Console.WriteLine("================="); }
#region 方式二 XmlDocument doc = new XmlDocument(); doc.Load("student.xml"); XmlNode no = doc.DocumentElement; foreach (XmlNode item in no.ChildNodes ) { //string name=item["name"].InnerText; //string age = item["age"].InnerText; //string sex = item["sex"].InnerText; Console.WriteLine("姓名:" + item["name"].InnerText); Console.WriteLine("年龄:" + item["age"].InnerText); Console.WriteLine("性别:" + item["sex"].InnerText); Console.WriteLine("======================="); }
第九章 文件操作
C# 读写一个文件需要以下5个基本步骤
1 创建文件流
2 创建阅读或者写入器
3 执行读写操作
4 关闭阅读或者写入器
5 关闭文件流
首先需要引入 System.IO 命名空间
创建文件流
FileStream myfs=new FileStream (String filepath,FileMode fileMode);
filePath 用于指定要操作的文件
fileMode 指定打开文件的模式(FileMode 枚举类型)
Create:用指定的名称新建一个文件,如果文件存在,则改写旧文件
CreateNew: 新建一个文件,如果文件存在会发生异常,提示文件已经存在
Open: 打开一个文件,指定的文件必须存在
OpenOrCreate:如果文件不存在,则用指定的名称新建一个文件并打开它
Append:打开现有文件,并在文件末尾追加内容
StreamRead读取器
StreamReader.ReadLine():读取文件流中的一行数据,并返回字符串
StreamReader.ReadToEnd():从当前位置读到末尾,并返回字符串
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; namespace Wenj { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //读取 private void button1_Click(object sender, EventArgs e) { FileStream fs = new FileStream("D:\Happy.txt",FileMode.Open); byte [] bytes=new byte [1024]; int count= fs.Read(bytes,0,bytes .Length); if (bytes!=null ) { string result = Encoding.Default.GetString(bytes, 0, count); txt1.Text = result; count = fs.Read(bytes, 0, bytes.Length); } fs.Close(); } //写入 private void button2_Click(object sender, EventArgs e) { FileStream fswrite = new FileStream("D:\Happy.txt", FileMode.Append ); string word = txt1.Text; byte[] bytes = Encoding.Default.GetBytes(word); fswrite.Write(bytes, 0, bytes.Length); MessageBox.Show("写入成功"); fswrite.Close(); } //复制 private void button3_Click(object sender, EventArgs e) { string fpath = ""; string tpath = ""; FileStream fromfs = new FileStream(fpath, FileMode.Open); FileStream tofs = new FileStream(tpath, FileMode.Create ); byte [] bytes=new byte [1024]; int count = fromfs.Read(bytes ,0,bytes .Length); //int i = 0; while (count !=0) { tofs.Write(bytes ,0,bytes .Length); count = fromfs.Read(bytes, 0, bytes.Length); MessageBox.Show("成功"); } tofs.Close(); fromfs.Close(); } private void Form1_Load(object sender, EventArgs e) { } } }
使用FileInfo类必须实例化对象