类
类的声明
class Example
{
}
class关键字前没有使用任何访问修饰符, 此时默认为internal(同一程序集内可访问)
类的成员
按级别分:静态成员和实例成员, 静态成员是类级别, 不属于类的实例, 而实例则属于实例
按功能分:字段, 属性, 方法, 索引器, 构造函数等
成员 | 说明 |
---|---|
常量 | 与类关联的常数值 |
字段 | 类的变量 |
方法 | 类可执行的计算和操作 |
属性 | 提供对私有字段的读写操作和访问控制 |
索引器 | 与以数组方式索引类的实例相关联的操作 |
事件 | 类生成的通知,以告知其他类或对象发生的相关事情 |
运算符 | 类所支持的转换和表达式运算符 |
构造函数 | 初始化类的实例或类本身所需的操作 |
析构函数 | 在永久丢弃类的实例之前执行的操作 |
类型 | 类所声明的嵌套类型 |
所有字段级变量被编译器初始化为其默认值
属性
C#属性是字段的扩展, 配合字段使用, 提供灵活的机制来读取、编写或计算私有字段的值,但实际上它是被称做“访问器”的特殊方法,是方法,所以不占用存储空间
private int age;
public int Age
{
get { return age; }
set { this.age = value; }
}
// 自动实现的属性
public string Name { get; set; }
get访问器的责任是返回字段的值, set访问器的责任是为字段赋值, 在属性中, 除了get和set访问器,不允许有其他方法出现。本质上,自动实现的属性这种语法也有自己的关联字段,只不过这个关联字段也是隐式的,是编译器自动生成的。需要注意的是,使用自动实现的属性,get和set访问器必须成对出现。
读写属性:
- 只读属性: 不具有set访问器或者set访问器为private级别的属性
- 只写属性: 不具有set访问器或者set访问器为private级别的属性
- 读写属性: 具有set访问器和get访问器
静态属性与静态变量、静态方法类似,使用static关键字即可, 属性和自动属性均可
对象
类是对数据和功能的封装,但封装不是目的,将类进行实例化并使用对象的数据和服务才是目的。
class People
{
public int Age { get; set; }
public string Name { get; set; }
}
People Susan = new People();
对象在实例化时,首先给People变量Susan在栈中分配内存,指向null,再在堆中新建一个People对象,并将其赋予变量Susan, 此时栈中的Susan就指向新创建的实例对象。
访问修饰符
- public: 最高访问级别,访问不受限制
- protected: 保护级别,受保护成员可由自身及派生类访问
- internal: 内部访问级别,只有在同一程序集内,内部类型或者成员才可访问
- protected internal: 内部保护级别,访问仅限于当前程序集,可由自身及派生类访问
- private: 私有访问,最低访问级别,只有在所在类中能够访问
访问修饰符,可用于类、字段、属性,而不可用于命名空间、局部变量、方法参数。
构造函数
构造函数是一类特殊的成员函数,用于为对象空间分配内存空间,并对类的数据成员进行初始化。构造函数分为实例构造函数和静态构造函数。
实例构造函数
实例构造函数有如下特点:
- 构造函数的名字必须和类同名
- 构造函数不允许有返回类型
- 构造函数可以具有0~n个参数
- 构造函数可以重载,以提供初始化类的不同方法
- 若在声明类时没有定义构造函数,则系统自动生成一个函数体为空的默认构造函数
- 可以对实例类构造函数使用public、protected、private修饰符
- 引用基类构造函数时使用base()方法,如果有参数则将参数传入,如base(参数1,参数2)
- 引用自身构造函数时使用this()方法,如果有参数则将参数传入,如this(参数1,参数2)
默认构造函数没有参数,同时函数体为空
实例构造函数都有一个访问修饰符,如果没有表示隐式的private修饰符,当前类只能通过自身进行实例化。
namespace LanguageTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
// error
// PrivateClass no = new PrivateClass();
PrivateClass yes = PrivateClass.GetInstance();
}
}
class PrivateClass
{
PrivateClass()
{
Console.WriteLine("PrivateClass init");
}
public static PrivateClass GetInstance()
{
return new PrivateClass();
}
}
}
静态构造函数用于初始化任何静态数据,或用于执行仅一次的特定操作。在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数。
静态构造函数具有几个特征:
- 不能使用任何访问修饰符
- 不能具有任何参数
- 执行时机:创建类的第一个实例,或者访问任何类的静态成员之前,自动执行的,并公执行一次
- 不能直接调用
- 无法控制执行静态构造函数的时机
对象初始化列表
People Susan = new People { Age = 10, Name = “Susan” };
People Susan = new People() { Age = 10, Name = “Susan” };
析构函数
当使用了窗口、文件和网络连接这类非托管资源时,应当使用析构函数释放这些资源
析构函数具有以下特点:
- 不能有访问修饰符
- 不能有参数
- 一个类只有一个析构函数
- 无法继承或重载
- 无法调用
- 无法预知何时被调用,因为它是被自动调用的
索引器
Class Sample
{
private string[] students = new string[3];
public string this[int studentNo]
{
get
{
return students[studentNo];
}
set
{
students[studentNo] = value;
- 每一个属性的名称必须唯一,而每一个索引器的签名必须唯一,不同的索引器签名可以实现索引器重载
- 索引器的“属性名”统一为this,而不能为其他,专门用以定义索引器
- 索引器的参数列表包含在方括号而不是圆括号之内
- 属性可以是静态的,而索引器只能为实例成员
- 属性的get访问器没有参数,而索引器的get访问器可以有参数,而且后者的get访问器和set访问器的参数相同
- 索引器可以有多个形参,比如访问多维数组时
分部类型和分部方法-修饰符:partial
拆分的场景:
- 当处理大型项目时,把一个类分布于多个独立文件中可以让多位程序员同时对该类进行处理
- 使用自动生成的源时,无须重新创建源文件便可将代码添加到类中
分部类:类的定义前加partial修饰符;分部类可以定义在两个不同的.cs文件中,也可以位于同一个.cs文件中;分部类必须同属一个命名空间。
分部方法:分部方法声明由两个部分组成,定义和实现。分部类方法的签名和它的可选实现可以位于一个或两个不同的分部类中。如果未提供分部方法的实现,则编译器将自动移除方法签名,以及对所有其他地方代码对该方法的调用。有如下限制:声明必须以上下文关键字partial开关;声明不能有访问修饰符,因此是隐式私有的;不能返回值;可以有ref参数,不能有out参数;分部方法可以使用static和unsafe修饰符;参数名称在实现声明和定义声明中虽然可以不同,但推荐使用一致的方法签名。