
建议:永远使用属性(而不是字段)来暴露数据,即字段永远是 private 或 protected 的。
字段只在类内部使用,类之间交换数据,永远只用属性。
什么是属性
使用 Get/Set 方法对之前:
class Program{static void Main(string[] args){var stu1 = new Student(){Age = 20};var stu2 = new Student(){Age = 20};var stu3 = new Student(){// 非法值,污染字段Age = 200};var avgAge = (stu1.Age + stu2.Age + stu3.Age) / 3;Console.WriteLine(avgAge);}}class Student{public int Age;}
使用 Get/Set 后:
class Program{static void Main(string[] args){try{Student stu1 = new Student();stu1.SetAge(20);Student stu2 = new Student();stu2.SetAge(20);Student stu3 = new Student();stu3.SetAge(200);int avgAge = (stu1.GetAge() + stu2.GetAge() + stu3.GetAge()) / 3;Console.WriteLine(avgAge);}catch (Exception ex){Console.WriteLine(ex.Message);}}}class Student{private int age;public int GetAge(){return this.age;}public void SetAge(int value){if (value >= 0 && value <= 120){this.age=value;}else{throw new Exception("Age value has error.");}}}
使用 Get/Set 来保护字段的方法至今仍在 C++、JAVA 里面流行(即 C++、JAVA 里面是没有属性的)。
因为 Get/Set 写起来冗长,微软应广大程序员请求,给 C# 引入了属性。
引入属性后:
class Program{static void Main(string[] args){try{Student stu1 = new Student();stu1.Age = 20;Student stu2 = new Student();stu2.Age = 20;Student stu3 = new Student();stu3.Age = 200;int avgAge = (stu1.Age + stu2.Age + stu3.Age) / 3;Console.WriteLine(avgAge);}catch (Exception ex){Console.WriteLine(ex.Message);}}}class Student{private int age;public int Age{get{return this.age;}set{if (value >= 0 && value <= 120){this.age = value;}else{throw new Exception("Age value has error.");}}}}
引入属性后代码简洁明了许多。
静态属性:
namespace tttlll{class Program{static void Main(string[] args){try{Student.Amount = -100;Console.WriteLine(Student.Amount);}catch (Exception ex){Console.WriteLine(ex.Message);}}}class Student{private static int amount;public static int Amount{get { return amount; }set{if (value >= 0){Student.amount = value;}else{throw new Exception("Amount must greater than 0.");}}}}
属性的声明
Code Snippet
- prop + 2 * TAB:属性的简略声明
- propfull + 2 * TAB:属性的完整声明
- private int age;
(1)用鼠标点击age,点击编辑→重构→封装字段 (2)将光标放在age上,Ctrl+RE
动态计算值的属性
主动计算,每次获取 CanWork 时都计算,适用于 CanWork 属性使用频率低的情况。
class Program{static void Main(string[] args){try{Student stu = new Student();stu.Age = 12;Console.WriteLine(stu.CanWork);}catch (Exception ex){Console.WriteLine(ex.Message);}}}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;}}}}
被动计算,只在 Age 赋值时计算一次,适用于 Age 属性使用频率低,CanWork 使用频率高的情况。
class Program{static void Main(string[] args){try{Student stu = new Student();stu.Age = 12;Console.WriteLine(stu.CanWork);}catch (Exception ex){Console.WriteLine(ex.Message);}}}class Student{private int age;public int Age{get{return age;}set{age = value;this.CalculateCanWork();}}private bool canWork;public bool CanWork{get { return canWork; }}private void CalculateCanWork(){if (this.age>=16){this.canWork = true;}else{this.canWork = false;}}}



