字段使类具备封装数据的能力,而属性是为了更好的保护字段的一种特殊方法。
一、字段
字段是一类对象内部数据的实际存储者,其他的一切方法都是对字段的加工。
从作用域上可以把字段分为共享字段和静态字段(如下声明),静态字段的特点是静态字段不属于任何对象,只属于类,必须要用 类名.静态字段名 进行访问,反过来通过 对象名.静态字段名 的方式是访问不到静态字段的。静态字段是可以重新赋值的,类名.静态字段名 = 新的值;静态字段的值为一个类的所有实体所共享;在概念上,它的值属于类所有,而不是类的每一个实体/对象所有
class student
{ //静态字段声明与初始化
public static int Amout=0;
static Student()
{
Amout++; //当有一个学生被静态构造时Amount加1
}
}
/*• 对于静态字段,它初始化的时机是在运行环境加载该数据类型时
• 即静态构造器初始化时
• 声明静态字段时设置初始化值与在静态构造器里面初始化静态字段其实是一样的*/
对于共享字段我们也不希望所有的实例化对象可以随心所欲的修改和读取,这时候就需要将该字段设为private,表示该字段不能直接由实例化对象来读写,但又不像静态字段一样只可以通过类名来操作,private表示除了该类型的创建者和类的内部成员函数之外,任何人都不能读写这些字段,这时候我们的实例化成员可以通过内部的属性提供的方法来间接修改。
还有一类特殊的字段称为只读字段(readonly),只读字段为实例或类型保存一旦初始化后就不希望再改变的值。
二、属性
我们既希望有一种方法能够限制实例化对象对字段的随意修改,又希望他能和修改字段数据的方式一样简单明了,属性就孕育而生了。
var stu1 = new Student();
stu1.Age=20; //属性的读写可以像字段一样方便
class Student
{
private int age;
//通过Age属性可以间接读写字段age
public int Age
{
get
{
return age;
}
set
{
if (value >= 0 && value <= 120) //对字段的读写添加了条件,限制了实例化对象对字节的直接修
{
age = value;
}
else
{
throw new Exception("Age value has error."); //不满足条件抛出异常
}
}
}
}
三、索引器
• 什么是索引器
• 索引器(indexer)是这样一种成员:它使对象能够用与数组相同的方式(即使用下标)进行索引
索引器一般都是用在集合上面,像如下示例这样用是很少见的(只是为了讲解方便)。
class Program
{
static void Main(string[] args)
{
var stu = new Student();
stu["Math"] = 90; //通过索引添加字段
stu["Math"] = 100;
var mathScore = stu["Math"];
Console.WriteLine(mathScore);
}
}
class Student
{
private Dictionary<string, int> scoreDictionary = new Dictionary<string, int>(); //定义一个字典型字段scoreDictionary
public int? this[string subject] //相当于一个返回值为int 或空传入参数为string的方法
{
get
{
if (scoreDictionary.ContainsKey(subject)) //确认字典中包含该索引
{
return scoreDictionary[subject];
}
else
{
return null;
}
}
set
{
if (value.HasValue == false)
{
throw new Exception("Score cannot be null");
}
if (scoreDictionary.ContainsKey(subject))
{
// 可空类型的 Value 属性才是其真实值。
scoreDictionary[subject] = value.Value;
}
else
{
scoreDictionary.Add(subject, value.Value);
}
}
}
}
四、常量
• 什么是常量
• 常量(constant)是表示常量值(即,可以在编译时计算的值)的类成员
• 常量隶属于类型而不是对象,即没有“实例常量”
• “实例常量”的角色由只读实例字段来担当
• 注意区分成员常量与局部常量
• 常量的声明
各种“只读”的应用场景
• 为了提高程序可读性和执行效率 —— 常量
• 为了防止对象的值被改变 —— 只读字段
• 向外暴露不允许修改的数据 —— 只读属性(静态或非静态),功能与常量有一些重叠
• 当希望成为常量的值其类型不能被常量声明接受时(类/自定义结构体) —— 静态只读字段