在C#中我們可以很自由的訪問共有字段,但有時我們可能需要某字段只能讀或者寫,或在改變字段值得時候做一些其他事情,顯然這些僅僅依靠字段是無法實現的,於是便有了屬性。
1、基本用法
c#中的屬性由屬性作用域中定義的get作用域(訪問方法)和set作用域(訪問方法)構成。
class Test { private int number; //int表示該屬性所封裝的數據類型 //數據類型必須與相應的字段(number)相同 public int Num { get{return number;} set{number=value;} } }
當封裝數據時,可能希望配置一個只讀屬性。為此,可以忽略set塊。類似,如果想擁有一個只讀屬性,就忽略get塊。
2、靜態屬性
C#靜態屬性可以是讀寫屬性,只讀屬性,只寫屬性中的任意一種。靜態訪問器適用於整個類,而不是類的實例。靜態屬性中的set,get訪問器只能訪問類的靜態成員。靜態屬性可以通過類名訪問,不能使用實例調用,這與靜態方法相同。
1 //簡單的儲蓄賬戶類 2 class SavingAccount 3 { 4 //實例級別的數據 5 public double currBalance; 6 7 //靜態數據點 8 private static double currInterestRate = 0.04; 9 10 //靜態屬性 11 public static double InterestRate 12 { 13 get{return currInterestRate;} 14 set{currInterestRate=value;} 15 } 16 }
3、自動屬性
自動屬性可以簡化封裝數據字段的過程,減輕了定義私有返回字段和相關c#屬性成員的工作。在定義自動屬性時,只指定訪問修飾符、實際的數據類型、屬性名稱和空的get/set作用域。在編譯時,編譯器為類型自動生成了私有返回字段和適當的get/set實現邏輯。
1 class Enemy 2 { 3 //自動屬性 4 public string Name{get;set;} 5 public int Life{get;set;} 6 public float Attack{get;set;} 7 8 }
注意:與傳統的屬性不同的是,不允許構建只讀或只寫的自動屬性,自動屬性定義是必須同時支持讀寫功能。但是定義更嚴格的get或set是可以的
4、關於自動屬性和默認值
可以直接在代碼中使用封裝了數字或布爾數據的自動屬性,因為隱藏的返回字段將設置一個可以直接使用的安全的默認值。但如果自動屬性封裝了另一個類變量,隱藏的私有引用類型的默認值將設為null。
例如下面的類spawn,使用了兩個自動屬性
1 class Spawn 2 { 3 //隱藏的int字段默認值為0 4 public int numbers{get;set;} 5 //隱藏的Enemy返回字段為null 6 public Enemy MyEnemy{get;set;} 7 }
當直接調用MyEnemy時,將會在運行時得到空引用異常,因為沒有為后台使用的Enemy成員變量設置新的對象。
由於私有的返回字段是在編譯時創建的,所以不能直接使用new關鍵字直接分配引用類型,必須在類的構造函數內部執行,以確保對象以安全方式誕生。
1 class Spawn 2 { 3 //隱藏的int字段默認值為0 4 public int numbers{get;set;} 5 //隱藏的Enemy返回字段為null 6 public Enemy MyEnemy{get;set;} 7 8 //必須用構造函數重寫分配給隱藏返回字段的默認值 9 public Spawn() 10 { 11 MyEnemy = new Enemy(); 12 numbers = 1; 13 } 14 15 public Spawn(Enemy enemy, int num) 16 { 17 MyEnemy = enemy; 18 numbers = num; 19 } 20 }