(C#)屬性(property)
屬性是字段和方法的一個交集。看起來像是一個字段,行為上又像是一個方法。
是類維持了封裝性,有可以方便地使用字段。
- 訪問屬性的語法和訪問一個字段(類成員)的語法是相同的。(
- 實際上,編譯器自動轉換為對特定accessor方法(取值和賦值方法統稱為accessor方法)的調用
屬性的聲明如下:
- AccessModifier Type PropertyName
- {
- get
- {
- //取值代碼 (get accessor )
- }
- set
- {
- //賦值代碼 (set accessor )
- }
- }
舉例如下:配置ScreenPosition 的屬性.
- struct ScreenPosition
- {
- //小寫的x,y是私有字段
- private int x, y;
- public ScreenPosition(int X, int Y)
- {
- this.x = rangeCheckedX(X);
- this.y = rangeCheckedY(Y);
- }
- //大寫的X,Y是公用屬性
- public int X
- {
- get { return this.x; }
- set { this.y = rangeCheckedX(value); }
- }
- public int Y
- {
- get { return this.y; }
- set { this.y = rangeCheckedY(value); }
- }
- private static int rangeCheckedX(int x) { ... }
- private static int rangeCheckedY(int y) { ... }
- }
使用屬性.
- ScreenPosition origin = new ScreenPosition ( 0, 0 ) ;
- int xpos = origin.X ; // 實際調用 origin.X.get
- origin.Y = 100 ; // 實際調用 origin.Y.set
只讀屬性 - 有get 沒有 set .
只寫屬性 - 有set 沒有 get
在接口中聲明屬性.
- 將get accessor 或 set accessor 主體替換成一個分號 .
- interface IScreenPosition
- {
- int X { get; set; }
- int Y { get; set; }
- }
既然有了Field(字段),又有了Property(屬性),那么在OOP的過程中,什么時候用Field,什么時候用Property呢?
一般的原則是,類的封裝性原則,Field為Private,類的實例中使用,而Property是類暴漏給外面的接口,可以進行讀取,設置操作。
(以下為翻譯文章)原文:http://msdn.microsoft.com/en-us/library/ms229006(v=vs.110).aspx
Property Design(屬性的設計)
盡管property從技術上看和method很相似,但是在使用場景上卻有很大的不同。property應該被看成一個智能的field,它具備field的使用語法,還擁有method的靈活性。
DO: 如果調用者不能修改property的值,那么創建一個get-only(只讀) 的property。
請記住如果property是一個可變的引用類型(mutable reference type), 即使property是get-only,property的值還是可以被修改的。
DO NOT: 不要提供一個set-only的property, 或者setter被getter有更多的控制權限。
例如:不要使用有一個public的setter和一個protected 的getter。
DO:為所有的property提供一個合理的默認值,確保默認值不會導致安全漏洞和非常低效的代碼。
DO: 運行property可以在任何順序下被set, 即使導致臨時的object的無效狀態。
DO: 如果property的set會產生一個異常,那么將保留之前的一個值。
AVOID: 避免從propery getter中產生異常。