一、字段(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、屬性里頭你可以寫代碼 做自己的驗證邏輯即 屬性除了公布字段外,還可以在屬性上添加對字段的約束規則,比如只讀,只寫,讀寫規則,還可以對屬性的值范圍設置等等。而字段則不可以 總之,字段能干的,屬性一定能干,屬性能干的,字段不一定干的了。另外從軟件設計的原則來看,屬性是方法,應當暴露,而字段是數據應當被封裝。