C#字段、属性、索引器、常量
C# 字段、属性、索引器、常量
- 一、字段
- 二、属性
- 三、索引器
- 四、常量
一、字段
定义:字段(field)是一种表示与对象或者类型(类与结构体)关联的变量
字段声明:特性(可选) 字段修饰符(可选) 类型 变量声明器;
(字段是写在类里面,写在函数体里的变量是局部变量)
实例字段:与对象关联的字段
class Program{static void Main(string[] args){Student stu = new Student();stu.Age = 20;stu.Score = 90;}}class Student{//Age和Score都是Student对象的实例字段public int Age;public int Score;}
静态字段:与类型关联的字段,也可以称为“成员变量”,由static
修饰
class Program{static void Main(string[] args){Student stu1 = new Student();stu1.Age = 20;stu1.Score = 90;Student stu2 = new Student();stu2.Age = 21;stu2.Score = 80;Student.ReportAmount();//输出2}}class Student{//Age和Score都是Student对象的实例字段public int Age;public int Score;//Amount是Student类的静态字段(成员变量)public static int Amount;public Student(){Student.Amount++;}public static void ReportAmount(){Console.WriteLine(Student.Amount);}}
字段的初始值
-
无显示初始化时,字段获得其类型的默认值
-
实例字段初始化时机:对象创建时
//实例字段初始化方法一:直接复值public int Age = 20;
//实例字段初始化方法二:在构造器里面 public Student() {Age = 20; }
-
静态字段初始化时机:类型被加载时
//静态字段初始化方法一:直接复值 public static int Amount = 100;
// 静态字段初始化方法二:在静态构造器里面 static Student() {Student.Amount = 200; }
只读字段:只有一次赋值机会
-
实例只读字段
class Program {static void Main(string[] args){Student stu = new Student(1);Console.WriteLine(stu.ID);//输出1stu.ID = 2;//报错} }class Student {public readonly int ID;public Student(int id){this.ID = id;}}
-
静态只读字段
class Program {static void Main(string[] args){Console.WriteLine(Brash.DefaultColor.Red);//输出0Console.WriteLine(Brash.DefaultColor.Green);//输出0Console.WriteLine(Brash.DefaultColor.Blue);//输出0} }struct Color {public int Red;public int Green;public int Blue;}class Brash {public static readonly Color DefaultColor = new Color() { Red = 0, Green = 0, Blue = 0 }; }
二、属性
定义:属性(property)是一种用于访问对象或者类型特性的成员,特性反映了状态
- 属性是字段的自然扩展
- 字段偏向于实例对象在内存中的布局,属性偏向于反映现实世界对象的特征
- 对外:暴露数据,数据可以储存在字段里,也可以是动态计算出来的
- 对内:保护字段不被非法值污染
- 属性由Get/Set方法对进化而来
class Program{static void Main(string[] args){try{Student stu1 = new Student();stu1.Age = 20;Student stu2 = new Student();stu2.Age = 30;Student stu3 = new Student();stu3.Age = 10;int avgAge = (stu1.Age + stu2.Age + stu3.Age) / 3;Console.WriteLine(avgAge);}catch (Exception ex){Console.WriteLine(ex.Message) ;}}}class Student{private int age;//属性,保护字段agepublic int Age{get{ return this.age;}set {if (value >= 0 && value <= 120){this.age = value;}else {throw new Exception("Age value has error");}}}}
属性的声明
特性(可选) 属性修饰符(可选) 类型 属性名 { get/set访问器}
-
完整的声明
方法一: 输入propfull
+连续两次Tab键private int myVar;public int MyProperty{get { return myVar; }set { myVar = value; }}
方法二:把鼠标放在字段名,按
Ctrl+R+E
-
简略声明, 输入
prop
+Tab键public int MyProperty1 { get; set; }
-
动态计算值的属性
class Program {static void Main(string[] args){Student stu1 = new Student();stu1.Age = 12;Console.WriteLine(stu1.CanWork);//输出False} }class Student {private int age;public int Age{get { return age; }set { age = value; }}//动态计算属性public bool CanWork{get{if (this.age >= 16){return true;}else{return false;}}} }
-
注意实例属性和静态属性
-
属性的名字一定是名词
-
只读属性,只有getter没有setter
属性与字段的关系
- 都是实体(对象或者类型)的状态
- 属性大多情况下是字段的包装器
- 建议使用属性来暴露数据,字段永远是private或者protected
三、索引器
索引器(indexer)是一种成员:它能使对象能够用与数组相同的方式(即使用下标)进行索引
class Program{static void Main(string[] args){Student stu1 = new Student();stu1["math"] = 90;var score = stu1["math"];Console.WriteLine(score);//输出90}}class Student{private Dictionary<string, int> scoreDictionary = new Dictionary<string, int>();//索引器,输入indexer+两次Tab键public int? this[string subject]{get{if (scoreDictionary.ContainsKey(subject)){return scoreDictionary[subject];}else{return null;}}set{if (value.HasValue){if (this.scoreDictionary.ContainsKey(subject)){this.scoreDictionary[subject] = value.Value;}else{this.scoreDictionary.Add(subject, value.Value);}}else{throw new Exception("Score cannot be null ");}}}}
四、常量
常量(constant)是表示常量值的类成员,必须赋值。只能声明基本数据类型
namespace System
{public static class Math{public const double E = 2.7182818284590451;public const double PI = 3.1415926535897931;}
}
- 常量隶属于类型而不是对象,没有“实例常量”
- “实例常量”的角色由只读字段来担当
- 区分成员常量(声明在类里)和局部常量(声明在函数里)
各种“只读”的应用场景
- 为了提高程序可读性和执行效率——常量
- 为了防止对象的值被改变——只读字段
- 向外暴露不允许修改的数据——只读属性(静态或者非静态)
- 当希望成为常量的值其类型不是基本数据类型时(类/自定义结构体)——静态只读字段
class Waspce {public const Building Location = new Building() { Address = "Some Address" };//报错 }class Building {public string Address { get; set; } }