属性
属性是代表类的实例或类中的一个数据项的成员,使用属性看起来非常像写入或读取一个字段,语法是相同的。
与字段相似之处:
●它是命名的类成员。
●它有类型。
●它可以被赋值和读取。
与字段不同之处:
●它不为数据存储分配内存。
●它执行代码。
属性是指定的一组两个匹配的,称为访问器的方法
●set访问器为属性赋值
●get访问权从属性获取值。
属性声明和访问器
set和get访问权有预定义的语法和语义。可以把set访问器想象成一个方法,带有单一参数“设置”属性的值。get访问器没有参数并从属性返回一个值。
●set访问器:
■拥有一个单独的,隐式的值参,名称为value,与属性的类型形同;
■拥有一个返回类型void。
●get访问器:
■没有参数;
■拥有一个与属性类型系统的返回类型。
注意事项
● get访问器的所有执行路径必须包含一条return语句,返回一个属性类型的值。
●访问器set和get可以以任意顺序声明,并且,除了这两个访问器外在属性上不允许有其他方法。
class C1
{
private int TheRealValue = 10;//后备字段:分配内存
public int MyValue//属性不分配内存
{
set { TheRealValue = value; }
get { return TheRealValue; }
}
}
public class Program
{
public static void Main(string[] args)
{
//C1 c = new C1();
//Console.WriteLine("MyValue: {0}",c.MyValue);
//c.MyValue = 20;
//Console.WriteLine("MyValue: {0}", c.MyValue);
//Console.ReadKey();
}
}
不能显示的调用get和set访问器
属性和关联字段
将字段声明为private以封装字段,并声明一个public属性来控制从类的外部对该字段访问。和属性关联的字段被称为后备字段或后备存储。
class C1{
private int TheRealValue = 10;//后备字段:分配内存
public int MyValue//属性不分配内存
{
set { TheRealValue = value; }
get { return TheRealValue; }
}
}
public class Program
{
public static void Main(string[] args)
{
//C1 c = new C1();
//Console.WriteLine("MyValue: {0}",c.MyValue);
//c.MyValue = 20;
//Console.WriteLine("MyValue: {0}", c.MyValue);
//Console.ReadKey();
}
}
执行其他计算
属性访问器并不局限与仅仅对管理的后备字段进传出数据。访问器get和set能执行任何计算。或不执行任何计算。唯一必须的行为是get访问需要返回一个属性类型的值。
只读和只写属性
要想不定义属性的某个访问器,可以忽略该访问器的声明。
● 只有get访问器的属性称为只读属性,只读属性是一种安全的,把一项数据从类或类的实例中传出去。而不允许太多访问方法。
● 只有set访问器的属性称为只写属性。只写属性是一种安全的,把一项数据从类的外部传入类,而不允许太多访问的方法。
●连个访问器中至少有一个必须定义,否则编译会产生一条错误消息。
属性与公共字段
属性比公共字段更好,理由如下:
●属性是函数型成员而不是数据成员,允许你处理输入和输出,而公共字段不行。
●属性可以只读或只写,而字段不行。
●编译后的变量和编译后的属性语义不同。
自动实现属性
因为属性经常被关联到后备字段,C#提供了自动实现属性,允许值声明属性而不声明后备字段,编译会为你创建隐藏的后备字段,并且自动挂到get和set访问器上。
自动实现属性的要点:
●不声明后备字段——编译器根据属性的类型分配存储。
●不能提供访问器的方法体——它们必须被简单的声明为分号。get担当简单的内存读,set担当简单的写。
●除非通过访问器,否则不能访问后备字段。因为不能用其他方法访问它,所以实现只读只写属性没有意义,因此必须同时以提供读写访问器。
静态属性
属性也可以声明为static,静态属性的访问器和所有静态成员一样,具有以下特点。
●不能访问类的实例成员——虽然他们能被实例成员访问。
●不管类是否有实例,它们都是存在的。
●当从类的外部访问时,必须使用类名引用,而不是实例名。