標籤:
一、欄位(field) 可以在聲明欄位的同時賦給它一個初始值。二、屬性(property)1、引入 假如將欄位聲明為public,則在類的外部都可以對該欄位進行訪問和更改,違背了類的封裝特性。如果聲明為private,則這種形式的封裝通常又過於徹底。例如,你可能希望欄位從外部唯讀,但從內部可以更改,但需要驗證對資料進行的更改。 以前,程式語言為了實現這些要求,採取的辦法是將欄位標記為私人,然後提供取值和賦值的方法來訪問和修改資料。遺憾的是,這樣做會影響類的可程式化性。無法再用賦值運算子來設定類中的資料。另外,要想訪問資料,只能調用方法來進行。 考慮到經常會用到這種設計模式,c#的設計者決定為它提供顯示的文法支援即屬性。2、構成 屬性的聲明看起來和欄位聲明一樣,但跟隨屬性名稱之後的是一對大括弧。在大括弧中,要添加具體的屬性實現代碼。兩個可選的部分構成了一個屬性的實現。其中,get標誌的屬性的取值方法部分,set標誌著屬性的賦值方法部分,它允許你調用欄位賦值文法。3、自動實作屬性 它允許在聲明一個屬性時,不實際的實現任何取值方法或賦值方法,也不聲明任何支援欄位。 例如: class Employee{ public string FisrtName //手動實現的屬性 { get { return _FirstName; } set { _FirstName=value} } private string _FirstName; //屬性FirstName的支援欄位 public string LastName { get; set;} // 自動實作屬性4、屬性作為虛欄位使用 即該屬性沒有支援欄位 在某些情況下,你甚至根本不需要一個支援欄位。你可以讓屬性的取值方法返回一個計算好的值,而讓賦值方法解析值,並把它持久儲存到其他一些成員欄位中。例子:class Employee{ public string FisrtName { get { return _FirstName; } set { _FirstName=value} } private string _FirstName; public string LastName { get { return _LastName ; } set { _LastName =value} } private string _LastName ; public string Name//屬性作為虛欄位使用 { get { returen FirstName+ " " +LastName;} set { string[] names=value.Split( new char[] { ‘ ‘} );// public String[] Split( params char[] separator) //separator :分隔此執行個體中子字串的 Unicode 字元數組、不包含分隔字元的空數組或 Nothing。 // 傳回值:一個數組,其元素包含此執行個體中的子字串,這些子字串由 separator 中的一個或多個字元分隔。 if(names.Length==2) { FirstName=names[0]; LastName=names[1];} else { throw new System.ArgumentException (string.Format("assigned value ‘{0}‘is invalid",value ) ) } } }} 5、唯讀和唯寫屬性 通過移除某個屬性的取值方法或賦值方法部分,可以改變屬性的可訪問型。只有賦值方法的屬性為唯寫屬性,這種情況很罕見。只提供取值方法的屬性為唯讀屬性,任何賦值企圖都會造成編譯錯誤。6、為屬性的取值和賦值方法指定存取修飾詞 (1)若不為屬性的賦值和取值方法指定存取修飾詞,則他們的存取修飾詞預設為屬性的存取修飾詞。 (2)在c#2.0中,可以為get或set部分指定存取修飾詞(但不能為兩者同時指定存取修飾詞),從而覆蓋了為屬性聲明指定的存取修飾詞。例如,在一個屬性中同時建立一個公用取值方法和一個私人賦值方法,是外部類只能對屬性進行唯讀訪問,而允許類內的代碼想屬性寫入。 (3)為取值或賦值方法指定存取修飾詞時,這個存取修飾詞的限制性必須必應用於整個屬性的存取修飾詞更嚴格。7、屬性和方法調用不允許作為ref或out參數值使用 ref和out參數值在內部實現時,需要將記憶體位址傳給目標方法。但是,由於屬性可能是沒有支援欄位的虛屬性,也有可能是唯讀或唯寫的,因此不可能傳遞其基礎儲存的地址。所以,不能將屬性作為ref或out參數值來傳遞。同樣地道理也使用於方法調用。如果需要將一個屬性或方法調用作為ref或out參數值來傳遞,首先必須將值複製到一個變數中,然後傳遞該變數。方法調用結束後,在將變數的值賦回屬性。8、屬性和其支援欄位的命名規範 假如屬性名稱為FirstName,那麼為該屬性提供支援的私人欄位來說,一些常見的命名規範是_FirstName和m_FirstName(延續自c++的一種命名規範,m代表member variable 成員變數)。另外,還可以採用camel大小寫規範(除第一個單詞外其餘單詞的首字母都大寫)。不管為私人欄位使用哪一種命名規範,都要依據pascal大小寫規範(每個單詞的首字母都大寫)來命名公用欄位和屬性。9、在類的內部關於欄位的訪問性問題 作為一個良好的編程習慣,我們應該只在屬性實現的內部訪問為屬性提供支援的欄位。即 我們使用的應該一直是屬性,而不要直接調用欄位。許多時候,即使是在包容屬性的那個類中,也不應該從屬性實現的外部存取它所支援的欄位。這樣一來,在為屬性添加了驗證邏輯或者其他額外的邏輯後,整個類就可以馬上利用那些邏輯。10、屬性和欄位的區別 @1、屬性可以唯讀或唯寫,公有成員一定是可讀寫的。 @2、屬性裡頭你可以寫代碼 做自己的驗證邏輯即 屬性除了公布欄位外,還可以在屬性上添加對欄位的約束規則,比如唯讀,唯寫,讀寫規則,還可以對屬性的值範圍設定等等。而欄位則不可以 總之,欄位能乾的,屬性一定能幹,屬效能乾的,欄位不一定乾的了。另外從軟體設計的原則來看,屬性是方法,應當暴露,而欄位是資料應當被封裝。
c# 欄位和屬性