使用屬性- C# 程式設計手冊 - Microsoft Docs
文章推薦指數: 80 %
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#程式設計指南
屬性
介面屬性
自動實作的屬性
本文內容
延伸文章資訊
- 1[C#.NET] 使用屬性(Property) 的好處| 余小章@ 大內殿堂- 點部落
[C#.NET] 使用屬性(Property) 的好處. 我相信很多人寫很久的程式從沒有習慣使用property,甚至連property 是什麼都不知道,長期以來都是一直 ...
- 2C# Properties (Get and Set) - W3Schools
C# also provides a way to use short-hand / automatic properties, where you do not have to define ...
- 3自動實作的屬性- C# 程式設計手冊 - Microsoft Docs
Its data can be modified from // outside the class. class Customer { // Auto-implemented properti...
- 4屬性- C# 程式設計手冊
_seconds = value * 3600; } } } class Program { static void Main() { TimePeriod t = new TimePeriod...
- 5C# 属性(Property) | 菜鸟教程
C# 属性(Property) 属性(Property) 是类(class)、结构(structure)和接口(interface)的命名(named)成员。类或结构中的成员变量或方法称为域(F...