C#的一些知识点

结构体

C# 中的结构体与 C/C++ 中的结构体有很大的不同,在 C# 中结构体具有以下功能:

结构体中可以具有方法、字段、索引、属性、运算符方法和事件;
结构体中可以定义构造函数,但不能定义析构函数,需要注意的是,定义的构造函数不能没有参数,因为没有参数的构造函数是 C# 默认自动定义的,而且不能更改;
与类不同,结构体不能继承其他结构体或类;
结构体不能用作其他结构体或类的基础结构;
一种结构体可以实现一个或多个接口;
结构体成员不能被设定为 abstract、virtual 或 protected;
与类不同,结构体可以不用 New 操作符来实例化,当使用 New 操作符来实例化结构体时会自动调用结构体中的构造函数;
如果不使用 New 操作符来实例化结构体,结构体对象中的字段将保持未分配状态,并且在所有字段初始化之前无法使用该结构体实例。

在设计结构体的时候需要注意的是:

不能为结构体声明无参数的构造函数,因为每个结构体中都已经默认创建了一个隐式的、无参数的构造函数;
不能在声明成员属性时对它们进行初始化,静态属性和常量除外;
结构体的构造函数必须初始化该结构体中的所有成员属性;
结构体不能从其他类或结构体中继承,也不能作为类的基础类型,但是结构类型可以实现接口;
不能在结构体中声明析构函数。

结构体与类的主要区别:

类是引用类型,结构体是值类型;
结构体不支持继承,但可以实现接口;
结构体中不能声明默认的构造函数。
类的默认访问权限修饰符是 internal,类中成员的默认访问权限修饰符是 private;
而结构体默认是Public

析构函数

特点:
析构函数只能在类中定义,不能用于结构体;
一个类中只能定义一个析构函数;
析构函数不能继承或重载;
析构函数没有返回值;
析构函数是自动调用的,不能手动调用;
析构函数不能使用访问权限修饰符修饰,也不能包含参数。

静态成员

若在定义某个成员时使用 static 关键字,则表示该类仅存在此成员的一个实例,也就是说当我们将一个类的成员声明为静态成员时,无论创建多少个该类的对象,静态成员只会被创建一次,这个静态成员会被所有对象共享。

静态属性
使用 static 定义的成员属性称为“静态属性”,静态属性可以直接通过 类名.属性名的形式直接访问,不需要事先创建类的实例。静态属性不仅可以使用成员函数来初始化,还可以直接在类外进行初始化。

静态函数
除了可以定义静态属性外,static 关键字还可以用来定义成员函数,使用 static 定义的成员函数称为“静态函数”,静态函数只能访问静态属性

多态之运算符重载

在C#中可以重载的运算符有一元运算符和二元运算符
一元运算符:+、-、!、~、++、–
二元运算符:+、-、*、/、%、&、|、^、<<、>>、=、!=、<、>、<=、>=

不可重载的有:
逻辑运算符:&&、||
强转类型换算符:(type)var_name
复合赋值运算符不能显式重载:+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=
但在重载二元运算符时,也会隐式重载相应的复合赋值运算符,例如重载了+运算符也会隐式的重载+=
其他的:^、=、.、?.、? : 、??、??=、…、->、=>、as、await、checked、unchecked、default、delegate、is、nameof、new、sizeof、stackalloc、switch、typeof 。

接口

定义: 接口可以看作是一个约定,其中定义了类或结构体继承接口后需要实现功能

特点:
接口是一个引用类型,通过接口可以实现多重继承;
接口中只能声明"抽象"成员,所以不能直接对接口进行实例化;
接口中可以包含方法、属性、事件、索引器等成员;
接口名称一般习惯使用字母“I”作为开头(不是必须的,不这样声明也可以);
接口中成员的访问权限默认为 public,所以我们在定义接口时不用再为接口成员指定任何访问权限修饰符,否则编译器会报错;
在声明接口成员的时候,不能为接口成员编写具体的可执行代码,也就是说,只要在定义成员时指明成员的名称和参数就可以了;
接口一旦被实现(被一个类继承),派生类就必须实现接口中的所有成员,除非派生类本身也是抽象类。
注意: 接口之间是可以继承的。例如可以使用接口 1 继承接口 2,当用某个类来实现接口 1 时,必须同时实现接口 1 和接口 2 中的所有成员

异常处理

在 C# 中,异常是在程序运行出错时引发的,例如以一个数字除以零,所有异常都派生自 System.Exception 类。异常处理则是处理运行时错误的过程,使用异常处理可以使程序在发生错误时保持正常运行。
C# 中的异常处理基于四个关键字构建,分别是 try、catch、finally 和 throw。
try: try 语句块中通常用来存放容易出现异常的代码,其后面紧跟一个或多个 catch 语句块;
catch: catch 语句块用来捕获 try 语句块中的出现的异常;
finally: finally 语句块用于执行特定的语句,不管异常是否被抛出都会执行;
throw: throw 用来抛出一个异常。

文件读写

文件是存储在磁盘中的具有特定名称和目录路径的数据集合,当我们使用程序对文件进行读取或写入时,程序会将文件以数据流(简称流)的形式读入内存中。我们可以将流看作是通过通信路径传递的字节序列,流主要分为输入流和输出流,输入流主要用于从文件读取数据(读操作),输出流主要用于向文件中写入数据(写操作)。

IO类
System.IO 命名空间中包含了各种用于文件操作的类,例如文件的创建、删除、读取、写入等等。如下表中所示:

IO类 描述
BinaryReader 从二进制流中读取原始数据
BufferedStream 临时存储字节流
Directory 对目录进行复制、移动、重命名、创建和删除等操作
DirectoryInfo 用于对目录执行操作
DriveInfo 获取驱动器的信息
File 对文件进行操作
FileInfo 用于对文件执行操作
FileStream 用于文件中任何位置的读写
MemoryStream 用于随机访问存储在内存中的数据流
Path 对路径信息执行操作
StreamReader 用于从字节流中读取字符
StreamWriter 用于向一个流中写入字符
StringReader 用于从字符串缓冲区读取数据
StringWriter 用于向字符串缓冲区写入数据

特性(Attribute)

解释: 特性(Attribute)是一种用于在程序运行时传递各种元素(例如类、方法、结构、枚举等)行为信息的声明性代码。使用特性可以将元数据(例如编译器指令、注释、描述、方法和类等信息)添加到程序中。.Net Framework 提供了两种类型的特性,分别是预定义特性和自定义特性。

特性具有的属性:
使用特性可以向程序中添加元数据,元数据是指程序中各种元素的相关信息,所有 .NET 程序中都包含一组指定的元数据;
可以将一个或多个特性应用于整个程序、模块或者较小的程序元素(例如类和属性)中;
特性可以像方法和属性一样接受自变量;
程序可使用反射来检查自己的元数据或其他程序中的元数据。

反射

反射(Reflection)是指程序可以访问、检测和修改它本身状态或行为的一种能力,反射中提供了用来描述程序集、模块和类型的对象,可以使用反射动态地创建类型的实例,并将类型绑定到现有对象,或者从现有对象中获取类型,然后调用其方法或访问其字段和属性。 如果代码中使用了特性,也可以利用反射来访问它们。

C# 中反射具有以下用途:
在运行时查看视图属性信息;
检查装配中的各种类型并实例化这些类型;
在后期绑定到方法和属性;
在运行时创建新类型,然后使用这些类型执行一些任务。

委托

C# 中的委托(Delegate)类似于 C 或 C++ 中的函数指针,是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用。委托特别适用于实现事件和回调方法,所有的委托都派生自 System.Delegate 类。在实例化委托时,可以将委托的实例与具有相同返回值类型的方法相关联,这样就可以通过委托来调用方法。另外,使用委托还可以将方法作为参数传递给其他方法。

特点:
委托类似于 C/C++ 中的函数指针,但委托是完全面向对象的。另外,C++ 中的指针会记住函数,而委托则是同时封装对象实例和方法;
委托允许将方法作为参数进行传递;
委托可用于定义回调方法;
委托可以链接在一起,例如可以对一个事件调用多个方法;
方法不必与委托类型完全匹配;
注意: 匿名函数等是特殊的委托。

多播委托:
委托对象有一个非常有用的属性,那就是可以通过使用 + 运算符将多个对象分配给一个委托实例,同时还可以使用 - 运算符从委托中移除已分配的对象,当委托被调用时会依次调用列表中的委托。委托的这个属性被称为委托的多播,也可称为组播,利用委托的这个属性,您可以创建一个调用委托时要调用的方法列表。

事件

在 C# 中,事件(Event)可以看作是用户的一系列操作,例如点击键盘的某个按键、单击/移动鼠标等,当事件发生时我们可以针对事件做出一系列的响应,例如退出程序、记录日志等等。C# 中线程之间的通信就是使用事件机制实现的。

事件需要在类中声明和触发,并通过委托与事件处理程序关联。事件可以分为发布器和订阅器两个部分,其中发布器是一个包含事件和委托的对象,事件和委托之间的联系也定义在这个类中,发布器类的对象可以触发事件,并使用委托通知其他的对象;订阅器则是一个接收事件并提供事件处理程序的对象,发布器类中的委托调用订阅器类中的方法(事件处理程序)。

学习事件的时候需要注意一下几点:

发布器确定何时触发事件,订阅器确定对事件作出何种响应;
一个事件可以拥有多个订阅器,同时订阅器也可以处理来自多个发布器的事件;
没有订阅器的事件永远也不会触发;
事件通常用于定义针对用户的操作,例如单击某个按钮;
如果事件拥有多个订阅器,当事件被触发时会同步调用所有的事件处理程序;
在 .NET 类库中,事件基于 EventHandler 委托和 EventArgs 基类。

在这文章中,也有许多没有列出来:譬如面向对象的三大特点-》封装、继承、多态。以及C#中的数据结构等,需要另行学习。
如有错误。望道友指出。^ _ ^

猜你喜欢

转载自blog.csdn.net/lml_w/article/details/127369352