属性
属性是特殊的方法,能让用户以字段的形式使用。
属性只能定义为类成员,不能定义局部属性。
声明属性
声明一个属性的语法为在一个字段后面加一对大括号。属性后面不需要加分号。
属性通常会控制一个字段。这种属性一般会使用和字段相似的名字。
比如字段以下划线开头,属性名字和字段其余部分一样。或是属性把开头第一个字母大写。
通常这种属性存在时,就不会把他控制的字段公开了。
class Monster
{
int hp;
int maxHp;
int atk;
public int Hp { }
}
此时,会得到一个错误:属性必须至少有一个访问器。
访问器
get访问器
属性里必须有至少一个访问器。
get访问器可以让属性能像变量一样被读取值。但是不能像变量一样接受赋值。
get访问器语法为关键字get+函数主体。没有函数名和参数列表。
get访问器等同于一个无参的函数,函数的返回值类型和属性的类型相同。
class Monster
{
int hp;
int maxHp;
int atk;
public double HpRatio
{
get
{
return 1.0 * hp / maxHp;
}
}
}
set访问器
set访问器可以让属性可以像字段一样接收赋值。
set访问器等同于一个无返回值,有一个类型为属性类型的参数的函数。
在set访问器内,使用关键字value获取参数。
class Monster
{
int hp;
int maxHp;
int atk;
public double HpRatio
{
get
{
return 1.0 * hp / maxHp;
}
set
{
hp = (int)(maxHp * value);
}
}
}
init访问器
init访问器是为了代替readonly用的,由于属性本体不能使用readonly修饰,这是一种替代方案。
有了init访问器后就不能存在set访问器了。
相对的,init可以为readonly字段赋值,而set访问器不行。
class Monster
{
int hp;
readonly int maxHp;
int atk;
public int MaxHp
{
get
{
return maxHp;
}
init
{
maxHp = value;
}
}
}
使用属性
通常,使用属性而不是直接公开字段,往往是因为要对获取的值先进行处理。
例如,当怪物的血量修改时不应该超过血量上限。
class Monster
{
int hp;
int maxHp;
int atk;
public int Hp
{
get
{
return hp;
}
set
{
if (value > maxHp)
value = maxHp;
hp = value;
}
}
}
使用属性,就像使用字段一样。
Monster Slim = new Monster();
Slim.Hp = 100;
Console.WriteLine(Slim.Hp);
如果访问器缺失,则这个属性可能是只读的,或是只写的。
何时使用属性
属性和方法在一定成度上可以相互转化,至于何时该使用方法,何时该使用属性没有明确的界限。
不过,以下特点可以作为区分属性和方法的一个参考。
方法视为操作语句,可以单独地放置在一行。
那么为什么要单独放置一行使用呢?肯定是因为这个操作会改变他的状态。
而属性不能单独放置,要么读取值,要么写入值。
也就是说这个功能从意图上来说不会改变他的状态。
class Taxi
{
public int Distance;//行驶距离
public int Operation;//运营时间
public int Fuel;//燃油
public void Refuelling()//加油,会改变字段
{
Fuel = 100;
}
public int AvgVelocity //平均速度,只根据字段计算的出,不会改变字段
=> Distance / Operation;
}