【C#学习】17字段,属性,索引器,常量

文章目录

  • 字段
      • 1.字段的本质和作用
      • 2.什么是实例字段,静态字段?
      • 3.如何把实例字段和静态字段关联起来?
      • 4.练习一下
      • 5.字段的声明
      • 6.初始化的时机
      • 7.字段修饰符 Readonly
  • 属性
      • 1.属性和字段的关系
      • 2.属性是怎么来的
      • 3.属性怎么声明?
        • 属性的完整声明:【propfull + 两下tab键】
        • 属性的简略声明:【prop + 两下tab键】
        • 需要注意区分的两种属性
        • 什么是动态计算值的属性?
  • 索引器
      • 1.索引器的声明:【ind + 两下tab键】
      • 2.强调
  • 常量
      • 1.什么是常量?
      • 2.区分成员常量和局部常量
      • 3.各种 "只读" 的应用场景
  • 待解问题

字段,属性,索引器,常量都是用来表达数据的类型成员
程序 = 数据 + 算法

C#中的类型(这里指类和结构体)都具有哪些成员?
【C#学习】17字段,属性,索引器,常量_第1张图片

字段

【C#学习】17字段,属性,索引器,常量_第2张图片

1.字段的本质和作用

字段的本质是变量,但与方法体当中的局部变量不同,后者是在方法运行时帮助方法暂时存储数据;而字段是用来为对象或类型存储数据的,那么,当一个对象或类型有多个字段时,这些字段的值就可组合起来表示该对象或类型的目前状态
字段的英文单词是 “field” ,表示一块数据存放的空间

2.什么是实例字段,静态字段?

  • 实例字段:帮助实例存储字段,实例字段的组合表示了该实例目前的状态
  • 静态字段:帮助类型存储字段,静态字段的组合表示了该类型目前的状态;静态字段用关键字 “static” 修饰
    【C#学习】17字段,属性,索引器,常量_第3张图片

3.如何把实例字段和静态字段关联起来?

【C#学习】17字段,属性,索引器,常量_第4张图片

4.练习一下

要求:每个学生都有其年龄和分数;整个班级有其平均年龄,平均分数和学生总数;假设,每个学生的分数是50加上各自的编号,每个学生年龄是20加上各自的编号;有100个学生,打印出平均分数和平均年龄;
【C#学习】17字段,属性,索引器,常量_第5张图片【C#学习】17字段,属性,索引器,常量_第6张图片

5.字段的声明

【C#学习】17字段,属性,索引器,常量_第7张图片

  • 字段的名字必须是名词(字段用以表达数据)

  • 提醒:字段 (field) 是一种表示与对象或类关联的变量的成员,所以,当一个类声明字段时,一定要写在类体当中,不能写在方法体中

在声明一个字段时就对其进行显式的初始化实际上与在构造器中对其进行初始化是一样的

//声明字段时就对其进行显式的初始化
class Student
{
	public int Age = 20;
}
//表示任何一个该类的实例被创建时,它的Age都会被设为20;

//效果与在类的构造器中进行初始化是一样的
class Student
{
	public int Age;
	public Student()
	{
		Age = 20;
	}
}

6.初始化的时机

即:初始化器什么时候对字段的值进行初始化?

  • 对于实例字段:在实例创建时(每次创建实例都会执行初始化任务)
  • 对于静态字段:在运行环境加载该数据类型时(永远只执行一次初始化任务,就是在第一次加载该数据类型时,数据类型只加载一次)

静态构造器就是把 “public” 改为 "static"

//静态构造器
class Student
{	
	public static int Amount;
	static Student()
	{
		Amount = 100;
	}
}
//静态构造器只在运行环境加载该数据类型时被调用一次

7.字段修饰符 Readonly

被 Readonly 修饰的字段称为 “只读字段”,顾名思义,就是只能读取该字段的值,并不能修改它的值

  • 只读字段的功能:为类型或实例保存一旦初始化就不希望再改变的值

所以,对于实例只读字段来说,只有一个机会去给它赋值,就是在声明该字段的时候直接跟一个初始化器初始化它的值(与在构造函数中初始化是一样的)

//比如一个学生的学号就很适合被写成只读字段
class Student
{
	public readonly int ID;
	public Student()
	{
		this.ID = int id
	}
}
//在创建实例时就会被编译器提醒输入一个ID值
  • 静态只读字段
    【C#学习】17字段,属性,索引器,常量_第8张图片

属性

1.属性和字段的关系

属性是字段的自然扩展,大多数情况下是字段的包装器,为了字段的值不被非法值污染,逐步由繁到简创建了现有的属性

//字段的值被非法值污染
Student stu1 = new Student(20);
Student stu2 = new Student(20);
Student stu3 = new Student(200);//手滑多输入一个0,字段值被污染
class Student
{
	public int Age;
	public Student(int age)
	{
		this.Age = age
	}
}

2.属性是怎么来的

(1)为了字段的值不被非法值污染,创建了Get()方法和Set()方法;
Get()方法用于获取字段的值;Set()方法用于设置字段的值;从而使得类或实例不能直接访问字段,而是需要调用这两种方法来达到获取或设置字段的值的目的
【C#学习】17字段,属性,索引器,常量_第9张图片

编程规范建议:当一个字段的修饰符由 “pubic” 变为 “private”(不能从外部直接访问),该字段命名方法变为驼峰法

为了不使程序崩溃,可在try语句中创建实例,用catch子句抓住异常,然后向用户传递异常消息
【C#学习】17字段,属性,索引器,常量_第10张图片

(2)但是Get(),Set()方法写起来确实有些冗长,所以微软创建了属性这个类型成员,实现了Get(),Set()方法的功能,但语言结构更简单,更清晰

3.属性怎么声明?

【C#学习】17字段,属性,索引器,常量_第11张图片

  • property-modifiers(opt):属性修饰符,最常见的两种是 “public” 和 “public static”
  • type :属性的数据类型,决定了当读取该属性时,会得到什么类型的值;以及当为该属性赋值时,可以为其赋什么类型的值
  • member-name :属性名字,因为属性是类的成员,所以称为member-name
  • { accessor-declarations }访问器,getter或setter;只有getter,称为只读属性;只有setter,称为只写属性;不过很少会用到只写属性,因为属性一个很重要的功能就是向外暴露数据,能够允许别人从这里读取数据

属性的声明包括完整声明和简略声明,这两者的区别在于如何去写getter和setter

属性的完整声明:【propfull + 两下tab键】

【C#学习】17字段,属性,索引器,常量_第12张图片
解释:在之前的Set()方法中,声明了 “value” 这个变量,用以接收实例中对字段设置的值;但是在属性中的setter却没有 “value” 这个变量的声明,这是因为微软已经为我们准备好了一个默认的变量,这个变量就是 value,变量名不能被修改;而且,value 是一个上下文关键字(指value这个单词在某个特定的代码上下文中是一个关键字,被高亮为蓝色),微软规定,在写setter访问器时,已经为我们准备好了一个叫 value 的关键字,它代表着传进来的由用户设置的值,当value出了setter这个范围,就不再是关键字

属性的简略声明:【prop + 两下tab键】

简略声明出来的属性在功能上与一个公有的字段是完全相同的,也就是说其值是不受保护的;属性的简略声明非常简单,代码简短,带有这种属性的类一般就是为了传递数据

需要注意区分的两种属性

(1)只读属性:没有setter
(2)不是只读属性,但是在 set 前加了 private,表示该属性的setter只能在当前类体中访问,不能在外界访问
【C#学习】17字段,属性,索引器,常量_第13张图片

什么是动态计算值的属性?

属性比字段更优越的一个地方体现在:属性可以实时动态地把值计算出来
举例说明:大于16的人可以去工作
【C#学习】17字段,属性,索引器,常量_第14张图片

索引器

【C#学习】17字段,属性,索引器,常量_第15张图片

1.索引器的声明:【ind + 两下tab键】

【C#学习】17字段,属性,索引器,常量_第16张图片

2.强调

(1)索引器一般都是用在集合类型中,用在非集合类型中的情况是非常少见的
(2)对于初学者很少有机会去写索引器

常量

【C#学习】17字段,属性,索引器,常量_第17张图片

1.什么是常量?

常量隶属于类型,常量的声明与字段非常类似,只是需要const关键字来修饰;常量 (constant) 是表示常量值(即,可以在编译时计算的值)的类成员;常量值:在编译器编译这段代码时,会拿这个值把常量的标识符给替换掉,从而提高程序运行效率

2.区分成员常量和局部常量

  • 成员常量:
//例如
Math.PI
Int.Maxvalue
//都是类的成员,当然也可以自定义
  • 局部常量:用于参与组成方法体当中的算法

3.各种 “只读” 的应用场景

(1)常量:隶属于类型,没有 “实例常量”

(2)只读字段:只有一个机会去进行初始化,就是在声明时后跟一个初始化器进行初始化,等价于在构造器中对其进行初始化

(3)只读属性:向外暴露数据时,建议使用属性,而该属性的值又不能更改,所以编写只读属性;
对于对象,使用实例只读属性;对于类型,使用静态只读属性;而且要分清真正的只读属性和把setter隐藏起来的属性;
当使用静态只读属性时,会发现其功能与常量有一些重叠,但要注意:常量在编译时,编译器会拿常量的值代替标识符,而静态只读属性没有这个功能,因而使用常量性能比较高(常量是类成员

(4)静态只读字段
常量的数据类型只能是基本的数据类型(int,double…),不能用类类型或自定义结构体类型作为常量的类型,这种情况下,就不能使用常量,必须使用静态只读字段

待解问题

如何在声明一个字段时后跟一个初始化器对其进行初始化

你可能感兴趣的:(C#学习)