C#程序设计 重点整理

C#知识点的重点整理(好多。。。。。。)


第三章 C#程序的流程控制

跳转语句

break语句可以用于switch,也可以用于循环。用于switch时表示跳出switch,用于循环时表示提前终止循环。

continue语句只能用于循环,不能用于switch,continue用于直接进入本循环的下一次循环操作,在while和do while中,continue立即转去检测循环控制表达式,以判定是否继续循环。

foreach语句

一种简单明了的方法循环访问数组或集合的元素,又称迭代器。

一般形式:

1
2
3
foreach (type varibles in expression) {
block;
}

其中,表达式一般是一个数组名或集合名,循环变量的类型必须与表达式的数据类型一致。

foreach执行过程:

  1. 自动指向数组或集合中第一个元素
  2. 判断该元素是否存在,如果不存在则结束循环
  3. 把该元素的值赋给循环变量
  4. 执行循环体语句块
  5. 自动指向下一个元素,跳转到第2步执行

使用例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
struct Contacter
{
public string name;
public string tel;
}

Contacter[] per = new Contacter[100];
int i = 0;

private void button1_Click(object sender, EventArgs e)
{
per[i].name = name.Text;
per[i].tel = number.Text;
i++;
lbl.Text = "名单+1";
}

private void button2_Click(object sender, EventArgs e)
{
bool isSearched = false;
foreach (Contacter c in per)
{
if (c.name == searchname.Text.Trim())
{
// Trim()吸收掉头尾多余空格
isSearched = true;
lbl.Text = "查找成功,号码为" + c.tel;
}
}
if (!isSearched)
lbl.Text = "找不到";
}

重复字符

过滤重复单字符:有两个变量ch_oldch_new,还有一个过滤后的字符串,一个代表上一个遍历到的字符,一个代表当前遍历到的字符,如果这俩相等那就不让新字符加入到过滤后字符串,否则就加入。

检索存在的重复二字词汇:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
int n = 0;
string[] words = new string[10];
int[] times = new int[10];
private void button1_Click(object sender, EventArgs e)
{
for (int i=0;i < txtbox.Text.Length - 2;i++)
{
bool isSame = false;
string source = txtbox.Text.Substring(i, 2);
int j = i + 2;
while (j < txtbox.Text.Length - 2)
{
string target = txtbox.Text.Substring(j, 2);
if (source == target)
{
times[n]++;
// 如果是新出现的重复词汇,则保存
if (Array.IndexOf(words, target) == -1)
{
isSame = true;
words[n] = target;
}
}
j++;
}
if (isSame)
n++;
}
lbl.Text = String.Format("一共有{0}个重复的词汇!\n\n其中,", n);
for (int i=0;i<10;i++)
{
if (!String.IsNullOrEmpty(words[i]))
lbl.Text += String.Format("'{0}'重复{1}次", words[i], times[i] + 1);
}

}

第四章 面向对象程序设计入门

面向对象的基本概念

  • 对象:客观世界中的任何一个物体,可以是自然物体,可以是逻辑结构。对象是构成系统的基本单位

    程序举例:写一个具体的object,标明属性和行为。

  • 事件:事件又称消息,表示对象A向对象B发出的服务请求。

    程序举例:某对象添加某事件

  • 方法:方法表示一个对象能完成的服务或执行的操作功能。

    程序举例:调用某对象的某方法

  • 类:把成千上万不同的对象归结为不同的类别,类表示具有相同属性和行为的一组对象的集合

    程序举例:写一个类

  • 抽象:处理事务复杂性的方法,只关注与当前目标有关的方面,而忽略与当前目标无关的方面

    程序举例:int是对所有整数的抽象,double是对所有浮点数的抽象等等

  • 封装:两个方面的含义。

    1. 将有关的数据和操作代码放在一个对象中,形成个基本单位,各个对象之间相对独立互不干扰。
    2. 将对象中的某些部分对外部隐藏,即隐藏内部细节,只留下少量借口,以便于与外界联系,接收外界的消息。它又被称为信息隐藏。

    程序举例:多个类有多个方法,互不干扰

  • 继承:建立新的类的时候在前一个类的基础上增加一些新的属性和行为,不必重新定义前一个类已经定义过的属性和方法。在C#中继承称为派生。

    程序举例:写一个类继承

  • 多态:是指在基类中定义的属性或方法被派生类继承后,可以表现出不同的行为特性,对同一消息会做出不同的响应。

    程序举例:多个派生类继承同一个类后,同一个方法有不同的操作

构造函数

构造函数的名称必须和类名相同,构造函数不允许有返回类型,构造函数的参数列表可以省略,也可以不包含任何语句。

使用例

1
2
3
4
5
6
7
8
class Student {
public string name;
public int age;
public Student(string name, int age) {
this.name = name;
this.age = age;
}
}

构造函数可以重载,在一个类中可以定义多个构造函数,提供不同的初始化方法,以满足不同需要。

对象的生命周期

.NET的公共语言运行时负责为变量分配内存,当程序运行结束时,需要回收它所占用的内存空间。值类型变量用栈来管理,方法调用结束时,这些变量所占用的内存被自动释放。引用型变量使用堆来管理,一旦使用new创建了对象,该对象会立即从堆中分配内存。但是当方法调用结束时,对象所占用内存并不会自动从堆中释放,只能通过.NET的垃圾回收器来回收。

一个对象的生命周期分为以下几个阶段。

  1. 使用new运算符创建对象并要求获得内存
  2. 自动调用构造函数并完成对象初始化
  3. 使用对象,包括访问数据成员,调用方法成员
  4. 释放对象所占用的资源,比如关闭磁盘文件、网络连接、数据库连接等
  5. 释放对象,回收内存(由垃圾回收器自动完成)

其中第四阶段可以通过终结器完成。终结器又叫析构函数,在对象销毁之前,.NET的公共语言运行时会自动调用析构函数并使用垃圾回收器回收对象占用的内存空间。

属性 字段

属性是类的一种成员,可以用作公共数据成员,通过读写操作提供更安全的数据访问机制。

使用例

1
2
3
4
5
6
7
8
9
10
public 类型 属性名 {
get {
return 私有字段;
}
set {
// 逻辑检查
// 私有字段 = value;
// value为C#保留字,代表外部赋给本属性的值
}
}

使用例2

1
2
3
4
5
6
7
8
class Test {
private double r;
public double R {
get => r;
set => t = (value < 0) ? 0 : value;
}
public double Area => 3.14 * R * R;
}

使用例3

1
2
3
4
5
6
7
8
9
10
11
// 自动实现的属性
public class Goods {
public string name {
get;
set;
}
public decimal Price {
get;
set;
}
}

字段表示类的成员变量,字段的值代表一个对象的数据状态。不同的对象,数据状态不同,意味着各字段的值也不同。

要让字段变成只读,加入readonly关键字。

1
public readonly string name = "下北泽昏睡红茶株式会社";

第五章 面向对象的高级程序设计

  • 静态成员:静态成员属于类但不属于类的实例,因此必须通过类来访问,而不能通过实例来访问。
  • 静态类:当类只包含静态成员时,C#建议用static关键字把它声明为静态类。由于静态类只包含静态成员,因此没有必要将它实例化。
  • 静态方法:操作静态字段的方法。
  • 类的继承性:在一个已存在的类的基础上定义一个新类。
  • 派生类:根据基类新定义的类

类的多态性

类的多态性:体现为一个派生类对基类的特征和行为的改变,表面上看这些特征或行为还是相似的。即同名函数不同功能(类似于重载)

多态性使用例

1
2
3
4
5
6
7
8
9
10
public class Animal {
public virtual string Eat() {
return string.Format("{0}吃东西", name);
}
}
public class Dog : Animal {
public override string Eat() {
return string.Format("{0}吃骨头", name);
}
}

注意:

  1. 字段不能虚拟,只有方法属性事件索引器可以虚拟
  2. 使用virtual修饰符后,不能再使用static,abstract,override
  3. 派生类对象即使被强制转换为基类对象,所引用的仍然是派生类成员
  4. 派生类可以通过密封来停止虚拟继承,此时使用sealed override

接口

接口是C#的一种引用数据类型。一个接口定义一个协定。接口可以包含方法、属性等成员,它只描述这些成员的签名(数据类型,名称,参数),不提供实现代码,具体实现由继承该接口的类来实现。实现某个接口的类必须遵守接口的协定,不能修改格式。

定义接口的访问修饰符只能是public和interval,默认为public,可以省略。为了与类相区别,接口的命名一般以I打头。

使用例

1
2
3
4
interface IUsb {
int MaxSpeed { get; }
string TransData(string from, string to);
}

实现接口使用例

1
2
3
4
5
6
7
8
9
10
public class Mp3 : IUSb {
public int MaxSpeed {
get {
reurn 480;
}
}
public string TransData(string from, string to) {
return string.Format("数据传输:从{0}到{1}", from, to);
}
}

接口支持继承,可以从一个接口派生一个新的接口。与类相比较而言,类只支持单继承,而接口允许多继承,即一个接口可以从多个基接口派生,多个基接口之间用逗号分隔。

C#允许类同时从基类和基接口派生,但要求类名必须位于基接口名的前面。

访问时注意安全,使用m is IBluetooth判断m对象是否符合某个接口,使用IUsb iu = m as IUsb;,判断iu != null也是可以的

访问使用例

1
2
3
Mp3 m = new Mp3();
IUsb iu = (IUsb)m;
lblShow.Text = iu.TransData("PC", "MP3 Device");

第六章 集合 索引器与泛型

集合

高度结构化方式存储任意对象的类,可以把一组类似的对象组合在一起。集合可以随意调整大小,而且为存储或检索某个对象提供了更多的方法。

ArrayList 是一个可动态维护长度的集合,又称动态数组。

HashTbale又称散列表,表示键/值对的集合。

索引器

方便访问集合类型的工具。表示通过哪一种类型的索引来存取数组或集合元素,可以是整型,也可以是字符串等。this表示本对象,可以简单把它理解成索引器的名字,因此不能为索引器指定名称。

泛型

通过“参数化类型”来实现在同一段代码中操作多种数据类型。泛型是一种编程范式,它利用“参数化泛型”将类抽象画,从而实现更为灵活的复用。泛型赋予代码更强的安全性、更好的复用、更高的效率和更清晰的约束。

第七章 程序调试与异常处理

当throw语句带有异常对象时,则抛出指定的异常类,并显示异常的相关信息。该异常既可以是预定义的异常类,也可以是自定义的异常类。

使用例

1
2
3
4
5
6
// 自定义异常类
class MyException : Exception
{
public MyException(string str1) : base(str1) { }
public MyException(string str1, Exception e) : base(str1, e) { }
}

第八章 基于事件驱动的程序设计技术

委托

为了确保事件处理程序被执行,在程序设计时必须预先将一个事件处理与事件源对象联系起来,这个操作称为事件的绑定,C#通过委托来绑定事件。委托是一种动态调用方法的类型,它与类、接口和数组相同,属于引用型。

委托是对方法的抽象和封装,类是对相同对象的抽象和封装。委托是实现动态调用方法的最佳办法,也是C#实现事件驱动的编程模型的主要途径。委托对象本质上代表了方法的引用。

委托的特点:

  1. 类似于C++的函数指针,但与指针不同的的是,委托是完全面向对象的,是安全的数据类型(是个面向对象语言都日常迫害C++危险指针系列)
  2. 委托允许将方法作为参数进行传递
  3. 委托可用于定义回调方法
  4. 委托可以把多个方法连接在一起,这样在事件触发时可同时启动多个事件处理程序
  5. 委托签名不需要与方法精确匹配

使用关键字delegate声明委托。使用例:

1
2
public delegate int Calculate(int x, int y);
// 传入参数不是两个int型变量,而是带有两个int型变量参数且返回值为int的函数

委托是一种特殊的数据类型,必须实例化之后才能用来调用方法。

实例化委托实际上就是创建一个对象,所以委托对象可以参与赋值运算,甚至作为方法参数进行传递。在使用委托对象调用所引用的方法时,必须保证参数的类型、个数、顺序和方法生命匹配。

使用例:

1
2
3
4
5
6
7
8
9
10
int Mul(int x,int y) {
return x * y;
}
int Div(int x,int y) {
return x / y;
}

Calculate a = new Calculate(Mul);
Calculate b = new Calculate(Div);
int result = a(3, 7); // 21

委托支持匿名函数实现,即声明委托时直接后跟大括号,计算return一个值,这一点和js有一点相似;同时也支持Lambda表达式,创建委托类型的匿名函数。

Lambda表达式与匿名函数使用例

1
2
3
4
5
6
7
8
public delegate int Calc(int x,int y) {
Calc handler = (x, y) => x * y;
int res = handler(5, 3);
}
// 相当于下面的
Calc handler = delegate(int x,int y) {
return x * y;
}

(隐式)多路广播:使用 + 或 += 将两个同类型的委托对象组合起来,使用 -= 移除一个委托对象。由于一个对象只能返回一个值,返回多个值时返回的是最后一个方法的值,因此为避免混淆,建议在使用多路广播时每个方法都使用void定义。

可以这么理解,如果有一个加法和减法的计算委托进行多路广播,并不是说某两个数先加再用这个值减,计算都是独立的,加就是加,减就是减,不会互相干扰;但是返回的值只能是减,这里默认先是有了加,然后组合了一个计算委托减。改进为void方法后,计算结果不能通过返回值传递,但是一个好办法是通过lblShow.Text在界面上打印。这样可以实现某两个数输入后按一下等号就能直接输出加减乘除的四个结果。

事件

触发事件的对象称为发布者,提供事件处理程序的对象称为订阅者,基于事件驱动模型的程序使用委托来绑定事件和事件方法。C#允许使用标准的EventHandler委托来声明标准事件,也允许先自定义委托,再声明自定义事件。

要想生成包含数据的时间,必须先自定义事件数据类型,然后再声明事件。

  1. 先自定义委托,再定义事件。
    使用例:

    1
    2
    3
    4
    5
    6
    public class ImageEventArgs : EventArgs {
    public int x;
    public int y;
    }
    public delegate void ImageEventHandler(Object sender, ImageEventArgs);
    public event ImageEventHandler onClick;
  2. 使用泛型EventHandler定义事件

    使用例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class TemperaureEventArgs : EventArgs {
    int temperature;
    public TemperaureEventArgs(int temp) {
    this.temperaure = temp;
    }
    public int Temperaure {
    get {
    return temperaure;
    }
    }
    }
    class TemperatureWarning {
    // 注意:使用泛型EventHandler必须指出事件数据类型。
    public event EventHandler<TemperaureEventArgs> OnWarning;
    // 声明温度预警委托类型
    public delegate void TemperatureHandler(object sender, TemperaureEventArgs e);
    // 声明温度预警事件
    public event TemperatureHandler OnWarning;
    }

要通过创建委托对象的方法把事件和事件方法联系起来(又称绑定事件或订阅事件)。负责绑定事件与事件方法的类就称为事件的订阅者。

预订事件的一般形式: 事件名+= new 事件委托类名(事件方法);

使用例

1
2
3
4
TemperaureWarning tw = new TemperaureWarning();
tw.OnWarning += new TemperaureWarning.TemperaureHandler(tw_OnWarning);
// 如果使用泛型
tw.OnWarning += new EventHandler<TemperaureEventArgs>(tw_OnWarning);

事件驱动模型步骤

  1. 定义事件相关信息类
  2. 在事件发布者类(事件源)中声明事件,并声明一个负责触发事件的方法
  3. 在事件接收者类中声明事件产生时调用的方法
  4. 在事件接收者类中订阅事件
  5. 在事件接收者类中触发事件

简单来说:首先确定是什么事,确定如果出事了要做什么,然后交给一个负责人,告诉他出事了就按这个方法做,这个负责人从现在起就开始负责这件事。然后某天出事了,这个负责人就按之前写好的方法做事情。

第十章 C#数据库编程技术

ADO.NET概述

ADO.NET是一种应用程序与数据源交互的API(应用程序编程接口),它支持的数据源包括数据库,文本,文件,excel表格或者XML文件等。可以说它是一种存在于.NET库的架构。主要两个组件是Data Provider和DataSet。

Data Provider提供了DataSet和数据库之间的联系,同时也包含了存取数据库的一系列接口。通过数据提供者所提供的API,可以轻松访问各种数据源的数据。

DataSet可简单理解成内存中的数据库,它是一种临时的数据库,只是临时保存从数据源中读出来的数据记录。在ADO.NET中,DataSet专门用来处理从数据源获得的数据,无论底层的数据是什么,都可以用相同的方式来操作从不同数据源获得的数据。

第十二章 高级数据访问与处理技术

XML

eXtensible Markup Language,简称XML,称之为可扩展的标记语言。设计初衷是为了弥补HTML的不足,将网络上传输的数据可视化,通过自定义的标记描述数据的结构。HTML只描述数据的显示方式,不能描述数据的结构和关系。XML文档是由标记和所标记的内容构造成的文本文件。

一个标准的XML文档由两部分组成,文档头部和文档主体。整个XML文档只能有一个根元素,其他所有元素包含在根元素里。子元素可以带属性,可以用属性名=属性值的语法规定属性。

要注意:

  1. 开始标记和结束标记没有空格
  2. XML区分大小写,保证开始标记和结束标记大小写一致
  3. 元素各属性之间用空格间隔
  4. 除了文本里的标点和属性值里的标点可以是中文,其他标点都是英文
  5. XML注释格式<!--注释内容-->,不能位于声明语句之前,或者开始标记和结束标记之内。

XML头<?xml version = "1.0" encoding = "utf-8"?>

DOM的基本思想是先把XML文档加载到内存并转换一棵树(DOM树),再随机访问或修改树的结点。因此,在XML文档数据不太大的情况下,通过DOM来操作XML文档显得更加方便。DOM树长得有点像这样,从根开始,每个结点下的子结点如果是叶节点则代表其父亲记录的属性,如果是子结点则代表另一条记录的名字……

代码不想放了,看课本例12-2和例12-3吧……

LINQ

语言集成查询(Language INtegrated Query),提供一种跨各种数据源和数据格式的解决方案,使得数据访问更加简单明了。

这部分内容我已经看傻了,到此结束,具体看课本吧。


-------------本文结束,感谢您的阅读转载请注明原作者及出处-------------


本文标题:C#程序设计 重点整理

文章作者:Shawn Zhou

发布时间:2019年12月22日 - 09:12

最后更新:2019年12月22日 - 18:12

原始链接:http://shawnzhou.xyz/2019/12/22/19-12-22-01/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

知识无价,码字不易。对您有用,敬请打赏。金额随意,感谢关心。
0%