使用屬性- C# 程式設計手冊 - Microsoft Docs

文章推薦指數: 80 %
投票人數:10人

C# 複製. public class Date { private int _month = 7; // Backing store ... the name field public string Name => _name; // the Name property }. 跳到主要內容 已不再支援此瀏覽器。

請升級至MicrosoftEdge,以利用最新功能、安全性更新和技術支援。

下載MicrosoftEdge 其他資訊 目錄 結束焦點模式 閱讀英文 儲存 共用 Twitter LinkedIn Facebook 電子郵件 WeChat 目錄 閱讀英文 儲存 目錄 閱讀英文 儲存 Twitter LinkedIn Facebook 電子郵件 WeChat 目錄 使用屬性(C#程式設計手冊) 發行項 03/23/2022 14位參與者 此頁面有所助益嗎? Yes No 還有其他意見反應嗎? 系統會將意見反應傳送給Microsoft:按下[提交]按鈕,您的意見反應將用來改善Microsoft產品和服務。

隱私權原則。

送出 謝謝。

本文內容 屬性會合併欄位和方法的各個層面。

對物件的使用者而言,屬性會呈現為欄位,而存取屬性需要相同的語法。

對於類別的實作器而言,屬性是一或兩個程式碼區塊,代表get存取子和(或)set存取子。

讀取屬性時,會執行get存取子的程式碼區塊;指派屬性的新值時,會執行set存取子的程式碼區塊。

沒有set存取子的屬性會視為唯讀。

沒有get存取子的屬性則視為唯寫。

具有這兩個存取子的屬性是讀寫。

在c#9和更新版本中,您可以使用init存取子來取代存取子set,將屬性設為唯讀。

與欄位不同,屬性不會分類為變數。

因此,您無法將屬性傳遞為ref或out參數。

屬性有許多用途:它們可以先驗證資料,再允許變更;它們會以透明方式公開類別上的資料,而該資料實際是從某個其他來源(例如資料庫)所擷取;資料變更時(例如,引發事件,或變更其他欄位的值),它們可以採取動作。

在類別區塊中宣告屬性的方式是指定欄位存取層級,其後依序接著屬性類型、屬性名稱,以及宣告get存取子和(或)set存取子的程式碼區塊。

例如: publicclassDate { privateint_month=7;//Backingstore publicintMonth { get=>_month; set { if((value>0)&&(value<13)) { _month=value; } } } } 在此範例中,將Month宣告為屬性,因此,set存取子可以確定設定的Month值介於1與12之間。

Month屬性使用私用欄位來追蹤實際值。

屬性資料的實際位置通常稱為屬性的「備份存放區」。

屬性通常會使用私用欄位作為備份存放區。

此欄位標示為私用,以確認只有呼叫屬性才能進行變更。

如需公用和私用存取限制的詳細資訊,請參閱存取修飾詞。

自動實作屬性提供簡單屬性宣告的簡化語法。

如需詳細資訊,請參閱自動實作的屬性。

Get存取子 get存取子的主體與方法的主體類似。

它必須傳回屬性類型的值。

執行get存取子相當於讀取欄位的值。

例如,當您要從get存取子傳回私用變數並啟用最佳化時,則編譯器會內嵌get存取子方法呼叫,因此沒有任何方法呼叫額外負荷。

不過,因為編譯器在編譯時間不知道執行階段實際呼叫的方法,所以無法內嵌虛擬get存取子方法。

下列get存取子會傳回私用欄位_name的值: classPerson { privatestring_name;//thenamefield publicstringName=>_name;//theNameproperty } 當您參考指派目標以外的屬性時,會叫用get存取子來讀取屬性的值。

例如: Personperson=newPerson(); //... System.Console.Write(person.Name);//thegetaccessorisinvokedhere get存取子必須結束於get或throw陳述式,而且控制無法離開存取子主體。

這是使用get存取子變更物件狀態的不良程式設計樣式。

例如,下列存取子會產生每次存取_number欄位時都變更物件狀態的副作用。

privateint_number; publicintNumber=>_number++; //Don'tdothis get存取子可用來傳回欄位值或計算它,並傳回它。

例如: classEmployee { privatestring_name; publicstringName=>_name!=null?_name:"NA"; } 在先前的程式碼區段中,如果您沒有指派值給Name屬性,它會傳回值NA。

Set存取子 set存取子與傳回型別為set的方法類似。

它使用稱為value的隱含參數,其類型為屬性的類型。

在下列範例中,將set存取子新增至Name屬性: classPerson { privatestring_name;//thenamefield publicstringName//theNameproperty { get=>_name; set=>_name=value; } } 當您指派屬性的值時,會使用提供新值的引數來叫用set存取子。

例如: Personperson=newPerson(); person.Name="Joe";//thesetaccessorisinvokedhere System.Console.Write(person.Name);//thegetaccessorisinvokedhere 在set存取子中使用區域變數宣告的隱含參數名稱value是錯誤的。

Init存取子 建立init存取子的程式碼與建立存取子set的程式碼相同,不同之處在于您使用init關鍵字而不是set。

差別init在於存取子只能用在函式中,或使用init。

備註 屬性可以標記為public、private、protected、internal、protectedinternal或privateprotected。

這些存取修飾詞定義類別使用者如何存取屬性。

相同屬性的get和set存取子可能會有不同的存取修飾詞。

例如,get可能是public以允許從類型外部進行唯讀存取,而set可能是private或protected。

如需詳細資訊,請參閱存取修飾詞。

屬性可以使用static關鍵字宣告為靜態屬性。

這可隨時向呼叫者提供屬性,即使沒有任何類別執行個體也是一樣。

如需詳細資訊,請參閱靜態類別和靜態類別成員。

屬性可以使用virtual關鍵字標示為虛擬屬性。

這可讓衍生類別使用override關鍵字覆寫屬性行為。

如需這些選項的詳細資訊,請參閱繼承。

覆寫虛擬屬性的屬性也可為sealed,指定它對衍生類別而言不再是虛擬。

最後,屬性可以宣告為abstract。

這表示類別中沒有任何實作,而且衍生類別必須撰寫自己的實作。

如需這些選項的詳細資訊,請參閱抽象和密封類別以及類別成員。

注意 在static屬性的存取子上使用virtual、abstract或override修飾詞是錯誤的。

範例 此範例示範執行個體、靜態和唯讀屬性。

它會從鍵盤接受員工姓名、將NumberOfEmployees增加1,並顯示員工姓名和編號。

publicclassEmployee { publicstaticintNumberOfEmployees; privatestaticint_counter; privatestring_name; //Aread-writeinstanceproperty: publicstringName { get=>_name; set=>_name=value; } //Aread-onlystaticproperty: publicstaticintCounter=>_counter; //AConstructor: publicEmployee()=>_counter=++NumberOfEmployees;//Calculatetheemployee'snumber: } classTestEmployee { staticvoidMain() { Employee.NumberOfEmployees=107; Employeee1=newEmployee(); e1.Name="ClaudeVige"; System.Console.WriteLine("Employeenumber:{0}",Employee.Counter); System.Console.WriteLine("Employeename:{0}",e1.Name); } } /*Output: Employeenumber:108 Employeename:ClaudeVige */ Hidden屬性範例 這個範例示範如何存取基類中的屬性,該屬性在衍生類別中具有相同名稱的另一個屬性隱藏: publicclassEmployee { privatestring_name; publicstringName { get=>_name; set=>_name=value; } } publicclassManager:Employee { privatestring_name; //Noticetheuseofthenewmodifier: publicnewstringName { get=>_name; set=>_name=value+",Manager"; } } classTestHiding { staticvoidMain() { Managerm1=newManager(); //Derivedclassproperty. m1.Name="John"; //Baseclassproperty. ((Employee)m1).Name="Mary"; System.Console.WriteLine("Nameinthederivedclassis:{0}",m1.Name); System.Console.WriteLine("Nameinthebaseclassis:{0}",((Employee)m1).Name); } } /*Output: Nameinthederivedclassis:John,Manager Nameinthebaseclassis:Mary */ 上述範例中的重點如下: 衍生類別中的Name屬性會隱藏基底類別中的Name屬性。

在這類情況下,new修飾詞用在衍生類別的屬性宣告中: publicnewstringName 轉型(Employee)用來存取基底類別中的隱藏屬性: ((Employee)m1).Name="Mary"; 如需隱藏成員的詳細資訊,請參閱new修飾詞。

覆寫屬性範例 在此範例中,Cube和Square這兩個類別會實作抽象類別Shape,並覆寫其抽象Area屬性。

請注意如何在屬性上使用override修飾詞。

程式接受這端作為輸入,並計算正方形和立方體的區域。

它也接受區域作為輸入,並計算正方形和立方體的對應端。

abstractclassShape { publicabstractdoubleArea { get; set; } } classSquare:Shape { publicdoubleside; //constructor publicSquare(doubles)=>side=s; publicoverridedoubleArea { get=>side*side; set=>side=System.Math.Sqrt(value); } } classCube:Shape { publicdoubleside; //constructor publicCube(doubles)=>side=s; publicoverridedoubleArea { get=>6*side*side; set=>side=System.Math.Sqrt(value/6); } } classTestShapes { staticvoidMain() { //Inputtheside: System.Console.Write("Entertheside:"); doubleside=double.Parse(System.Console.ReadLine()); //Computetheareas: Squares=newSquare(side); Cubec=newCube(side); //Displaytheresults: System.Console.WriteLine("Areaofthesquare={0:F2}",s.Area); System.Console.WriteLine("Areaofthecube={0:F2}",c.Area); System.Console.WriteLine(); //Inputthearea: System.Console.Write("Enterthearea:"); doublearea=double.Parse(System.Console.ReadLine()); //Computethesides: s.Area=area; c.Area=area; //Displaytheresults: System.Console.WriteLine("Sideofthesquare={0:F2}",s.side); System.Console.WriteLine("Sideofthecube={0:F2}",c.side); } } /*ExampleOutput: Entertheside:4 Areaofthesquare=16.00 Areaofthecube=96.00 Enterthearea:24 Sideofthesquare=4.90 Sideofthecube=2.00 */ 另請參閱 C#程式設計指南 屬性 介面屬性 自動實作的屬性 本文內容



請為這篇文章評分?