C#中的属性

属性是代表类的实例或类中的一个数据项的成员 。属性指的是一组两个匹配的、称为访问器的方法:
public返回类型标识符{set 访问器为属性赋值get 访问器为属性获取值}
set访问器总是:
get访问器总是:
属性跟字段的相同点:
属性跟字段的不相同点:
访问器的重点如下:
使用属性
写入和读取属性的访问器时,会被隐式调用:
注意: 不能显式地调用访问器,就跟调用函数那样, 会出现编译错误 。
namespace Ch05Ex03{class D// 属性本身不分配内存{private double name = 3.14;// 为字段分配内存public double MyValue{set{name = value; //返回类型为void}get{return name;// 返回类型是属性的类型,属性的类型也要跟字段的数据类型一致}}}class Program{static void Main(string[] args){D myD = new D();myD.MyValue = http://www.kingceram.com/post/5.666;//给访问器中的字段赋值WriteLine(myD.MyValue);//输出赋值后的字段的值var tmp = myD.MyValue; WriteLine(tmp);//输出赋值后的字段的值var tt = myD.get(); // 错误, 不能这样显式调用myD.set(5.3); // 错误, 不能这样显式调用ReadKey();}}}
我们经常将类中的字段声明以封装该字段, 然后声明一个的属性来控制从类的外部对该字段的访问 。和属性关联的字段称为后备字段或后备存储 。
属性和后备字段需要注意的问题有:
privatedouble nameField = 3.14; //第一种约定public double NameFild{set{nameField = value;}get{return nameField;}}
privatedouble _nameField = 3.14;// 第二种约定public double NameFild{set{_nameField = value;}get{return _nameField;}}
利用 set 和 get 访问器 执行其它运算
属性访问器不仅仅只可以对关联的字段传入传出数据, 还可以执行任何计算,或者不执行任何计算 。但是get访问器必须返回一个属性类型的值 。
【C#中的属性】下面看一个更有用的示例:
namespace Ch05Ex03{class D{privatedouble _nameField = 3.14;public double NameFild{set{_nameField = value > 100 ? 100 : value;//执行计算}get{return _nameField;}}}class Program{static void Main(string[] args){D myD = new D();myD.NameFild = 200;//给访问器中的字段赋值WriteLine(myD.NameFild);//输出赋值后的字段的值ReadKey();}}}
只读和只写属性使用属性比使用公共字段更好
属性比公共字段更好,理由如下:
自动实现属性
自动实现属性:允许只声明属性而不声明后备字段 。编译器会为你创建隐藏的后备字段, 并且自动挂接到get 和 set 访问器上 。
自动实现属性的要点如下:
namespace Ch05Ex03{class D{public double NameFild//分配内存{set;get;}}class Program{static void Main(string[] args){D myD = new D();myD.NameFild = 200;//给访问器中的字段赋值WriteLine(myD.NameFild);//输出赋值后的字段的值ReadKey();}}}
除了方便之外,自动实现的属性还允许您轻松地插入一个属性,本来那里您可能想要声明一个公共字段的 。
静态属性
属性也可以声明为 ,静态属性的访问器和所有静态成员一样,具有以下特点:
namespace Ch05Ex03{class D{public static int MyValue{get; set;}public void PrintValue(){WriteLine($"输出值为:{MyValue}");}}class Program{static void Main(string[] args){WriteLine($"先输出静态属性的值:{D.MyValue}");D.MyValue = http://www.kingceram.com/post/10;// 在类的外部设置静态属性的值WriteLine($"再输出静态属性的值:{D.MyValue}");ReadKey();}}}
再看一个示例程序:
namespace Ch05Ex03{class D{int aa = 12;static int bb;public static void Show(){WriteLine($"输出bb的值:{bb}");//WriteLine($"输出bb的值:{aa}");错误,静态成员函数不可以输出非静态成员数据}public void PrintValue(){WriteLine($"输出bb的值:{bb}"); // 非静态的成员函数可以输出静态字段的值WriteLine($"输出aa的值:{aa}");}public static int MyValue{set{//aa = value; //错误,静态属性不可以访问非静态字段bb = value; //正确,静态属性可以访问静态字段}get{return bb;}}}class Program{static void Main(string[] args){WriteLine($"先输出静态属性的值:{D.MyValue}");D.MyValue = http://www.kingceram.com/post/100;// 在类的外部设置静态属性的值WriteLine($"再输出静态属性的值:{D.MyValue}");D myD = new D();myD.PrintValue();ReadKey();}}}输出结果为:先输出静态属性的值:0再输出静态属性的值:100输出bb的值:100输出aa的值:12