类与类成员

C#类访问限制:

public class可以被任意程序集所见、internal class仅能被自身程序集所见、static class常用来封装静态属性方法和扩展方法。

C#类的成员分为:

静态成员:字段、常量。

函数成员:属性、方法、索引器、事件、运算符、构造函数、析构函数。

C#成员访问限制:

public、static(静态)、private(仅限当前类内)、internal(仅限当前程序集)、protected(仅限当前类与该类的子类)

非静态成员就是函数成员。

属性

只用成员既有get又有set时才允许使用访问修饰符。
虽然两个访问器都必须出现但他们中只能有一个有访问修饰符。
访问器的修饰符限制必须比成员访问级别更严格。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
class Program {
static void Main(string[] args) {
Student student = new Student();
student.age = -10;
Console.WriteLine(student.age);// 1
student.age = 10;
Console.WriteLine(student.age);// 10
}
}
class Student {
private int _age=1;
public int age {
get{
return _age;
}
set {
if(value > 0 && value < 150) {
_age = value;
}
}
}
public string name { get; private set; }//自动实现属性
}

方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System;
class Program {
static void Main(string[] args) {
Student std = new Student();
std.Eat();//实例方法
Student.Study();//静态方法
}
}
class Student {
public static void Study() {
Console.WriteLine("I can study");
}
public void Eat() {
Console.WriteLine("I can eat");
}
}

构造函数

构造函数必须和类名相同,且不能有返回值(连void都没有)。静态构造函数用static声明,类只能有有一个静态构造函数且不能带参数,静态构造函数不能有访问修饰符。
静态构造函数不能访问所在类的实例成员,因此不能使用this访问器,不能显式调用静态构造函数

1
2
3
4
5
6
7
8
9
    public string name { get; set; }
public static string school{ get; set; }
public Student(string name) { //构造器
this.name = name;
}
static Student() {//静态构造函数
school = "清北大学";
}
}

对象初始化语句

1
2
Student std = new Student() { name = "张三" };
Student std - new Student { name = "张三" };

注意静态字段和属性不能通过该方式初始化。

const修饰符

const修饰符用于字段声明时,const字段使用方式和静态字段一样,几遍没有实例依然可以使用。
如果是static字段,初始化必须在静态构造函数中完成。
const字段相当于C/C++中的#define,它在内存中没有存储位置

readonly修饰符

const只能在字段声明中初始化,const的行为总是静态的。readonly字段可以使实例字段,也可以是静态字段,它在内存中有存储位置。
readonly允许在不同环境或不同构造函数中设置不同的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Student{
public const string School = "山河大学";
public readonly string Principal;//未初始化
public string name { get; set; }
public int age { get; set; }
public Student() {
this.Principal = "刘校长";
}
public Student(int age) {
this.age = age;
this.Principal = "高校长";
}
}

你可能会好奇为什么会有两个构造函数,别担心,我会在之后的章节中介绍的函数重载详细说明。

索引器

索引器可以帮助我们以自己想要的方式调用和读取类的成员,索引器不用分配内存在这点索引器和属性的原理一样,不过属性用来表示单个数据成员而索引器用来表示多个成员。
索引的是一组get和set访问器。
索引器的参数列表在方括号中间,至少声明一个参数。

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
class Program {
static void Main(string[] args) {
Student student = new Student();
student[0] = "学号:2002220115";
student[1] = "姓名:张三";
Console.WriteLine(student[0]);
Console.WriteLine(student[3]);
}
}
class Student {
public string id;
public string name;
public string this[int i] {
get {
switch(i) {
case 0:return id;
case 1:return name;
default: return "请在0-1中选择索引";
}
}
set {
switch (i) {
case 0: id = value;break;
case 1: name = value;break;
}
}
}
}

索引器重载

只要索引器的参数列表不同(返回值不同是不够的),类就可以有多个索引器。

1
2
3
4
5
6
7
8
9
10
class Student{
public string this[int index]{
get{...}
set{...}
}
public string this[int index1 , int index2]{
get{...}
set{...}
}
}

分部类与分部方法(partial class)

分部类:
类的声明可以分割成几个分部类的声明。
每个分部类的声明都含有一些类成员的声明。
类的分部类声明可以在同一文件中也可以在不同文件中。

1
2
3
4
5
6
    public string id;
public string name;
}
partial class Student {
public int age;
}

分部方法:
方法的不同部分可以声明在分部类的不同部分中。
声明的实现部分只是一个分号,在实现部分以语句块方式实现

1
2
3
4
5
6
7
8
9
10
11
partial class Student {
public string id;
public string name;
public void study(int x);//定义分部方法
}
partial class Student {
public int age;
public void study(int x){//实现分部方法
Console.WriteLine(x);
}
}