文章目錄
- 屬性的多線程支援
- 屬性是通過方法來實現的,那麼自然屬性也擁有方法的所有語言特徵(abstract,Interface,virtual...)
屬性允許將資料成員作為公用介面的一部分暴露出去,同時仍舊提供物件導向環境下所需要的封裝。屬性這個語言元素可以讓你像訪問資料成員一樣使用,但底層依舊使用方法實現。通過使用屬性我們可以建立出類似於資料訪問(客戶代碼在訪問屬性時,就像是在訪問共有的欄位),但實際上確是方法調用的介面,自然也可以享受到方法調用的所有好處。
在.NET Framework中,資料繫結類僅支援屬性,而不支援公有資料成員。對於所有的資料繫結類庫均是如此,包括WPF、Windows Forms和Silverlight。
關於資料繫結:
資料繫結就是將某個對象的一個屬性和某個使用者介面控制項相互關聯起來。資料繫結機制使用反射來找到類型中的特定屬性
下面的代碼錶示:將txt_City控制項的Text屬性綁定到了Address對象的City屬性上。
this.txt_City.DataBindings.Add("Text", address, "City");
使用屬性使我們可以更容易應對變化,當日後產生新的需求或行為時,屬性更加易於修改。假如,客戶對象不應該有空白的名稱。若使用的公有屬性來封裝Name,那麼只需要這樣簡單的修改即可:
1 public class Customer 2 { 3 private string name; 4 public string Name 5 { 6 get { return name; } 7 set 8 { 9 if (string.IsNullOrEmpty(value))10 {11 throw new ArgumentException("不能使用空白名稱", "Name");12 }13 name = value;14 }15 }16 }
屬性的多線程支援
因為屬性是通過方法來實現的,所以添加多線程支援也非常簡單。只需下面的簡單修改可以支援對資料的同步訪問:
1 public class Customer 2 { 3 private object syncHandle = new object(); 4 5 private string name; 6 public string Name 7 { 8 get 9 {10 lock (syncHandle)11 return name;12 }13 set14 {15 if (string.IsNullOrEmpty(value))16 {17 throw new ArgumentException("不能使用空白名稱", "Name");18 }19 lock (syncHandle)20 name = value;21 }22 }23 }
屬性是通過方法來實現的,那麼自然屬性也擁有方法的所有語言特徵(abstract,Interface,virtual...)
屬性可以定義為virtual的:
1 public class Customer2 {3 //C#3.0隱式屬性文法(不需要驗證getter或setter邏輯時)4 public virtual string Name5 { 6 get;7 set;8 }9 }
也可以將屬性聲明為抽象(abstract)的,以類似隱式屬性文法的形式定義在介面中。介面只是定義了一個契約,強制所以實現了該介面的類型都必須滿足,如下:
1 public interface INameValuePair<T> 2 { 3 string Name 4 { 5 get; 6 } 7 8 T Value 9 {10 get;11 set;12 }13 }
屬性的訪問器將作為兩個獨立的方法編譯到你的類型中,我們可以為屬性的get和set訪問器制定不同的存取權限以實現更精確的控制:
1 public class Customer2 {3 public virtual string Name4 {5 get;6 protected set;7 }8 }
通過屬性返回序列中的項,我們可以看到List<T>類的Item屬性(所有得索引器都是使用this關鍵字聲明的):
1 public T this[int index]2 {3 get;4 set;5 }
小節:
無論何時需要在類型的公有或保護介面中暴露資料,都應該使用屬性。你也應該使用索引器來暴露序列或字典。所有的資料成員都應該是私人的,沒有任何例外。這樣你就立即得到了資料繫結的支援,也便於日後對方法實現進行各種修改。
閱讀書目:《Effective C#》