C#中的屬性解析(get、set、value)
C#中的屬性(get、set、value)
C#語言在面向?qū)ο笤O(shè)計(jì)和編程中對數(shù)據(jù)安全提出了嚴(yán)格的要求,其中一個(gè)重要的原則就是數(shù)據(jù)封裝。根據(jù)這一原則,C#程序設(shè)計(jì)中要求開發(fā)人員對特定類的數(shù)據(jù)字段盡量不以公有方式提供給外界。因此在類內(nèi)部多數(shù)字段的訪問權(quán)限被限定為private或是public,而這些字段與外界的交流經(jīng)常采用屬性來進(jìn)行。
屬性使類能夠以一種公開的方法獲取和設(shè)置值,同時(shí)隱藏實(shí)現(xiàn)或驗(yàn)證代碼。
屬性是這樣的成員:它們提供靈活的機(jī)制來讀取、編寫或計(jì)算私有字段的值。
可以像使用公共數(shù)據(jù)成員一樣使用屬性,但實(shí)際上它們是稱作“訪問器”的特殊方法。這 使得可以輕松訪問數(shù)據(jù),此外還有助于提高方法的安全性和靈活性。
屬性使類能夠以一種公開的方法獲取和設(shè)置值,同時(shí)隱藏實(shí)現(xiàn)或驗(yàn)證代碼。
get 屬性訪問器用于返回屬性值,而 set 訪問器用于分配新值。 這些訪問器可以有不同的訪問級別。
get 訪問器體與方法體相似。 它必須返回屬性類型的值。執(zhí)行 get 訪問器相當(dāng)于讀取字段的值
get 訪問器必須以 return 或 throw 語句終止,并且控制權(quán)不能離開訪問器體。
value 關(guān)鍵字用于定義由 set 取值函數(shù)分配的值。
不實(shí)現(xiàn) set 取值函數(shù)的屬性是只讀的。
屬性的定義通常由以下兩部分組成:
1、需要封裝的專用數(shù)據(jù)成員
private int _nValue = 1; private double _dValue = 10.101; private char _chValue = 'a';
2、向外界提供訪問的公共屬性:
//讀寫屬性nValue: public int nValue { ? ? get ? ? { ? ? ? ? return _nValue; ? ? } ? ? set ? ? { ? ? ? ? _nValue = value; ? ? } ?? } //只讀屬性dValue: public double dValue { ? ? get ? ? { ? ? ? ? return _dValue; ? ? } } //只寫屬性chValue: public char chValue { ? ? set ? ? { ? ? ? ? _chValue = value; ? ? } }
當(dāng)屬性的訪問器中不需要其他邏輯時(shí),自動實(shí)現(xiàn)的屬性可使屬性聲明更加簡潔??蛻舳诉€可以通過這些屬性創(chuàng)建對象,例如下面的代碼,編譯器將創(chuàng)建一個(gè)私有的匿名支持字段,該字段只能通過屬性的get和set訪問器進(jìn)行訪問。
class Customer { ? // Auto-Impl Properties for trivial get and set ? ? public double TotalPurchases { get; set; } ? ? public string Name { get; set; } ? ? public int CustomerID { get; set; } ? ? // Constructor ? ? public Customer(double purchases, string name, int ID) ? ? { ? ? ? ? TotalPurchases = purchases; ? ? ? ? Name = name; ? ? ? ? CustomerID = ID; ? ? } ? ? // Methods ? ? public string GetContactInfo() {return "ContactInfo";} ? ? public string GetTransactionHistory() {return "History";} ? ? // .. Additional methods, events, etc. } class Program { ? ? static void Main() ? ? { ? ? ? ? // Intialize a new object. ? ? ? ? Customer cust1 = new Customer ( 4987.63, "Northwind",90108 ); ? ? ? ? //Modify a property ? ? ? ? cust1.TotalPurchases += 499.99; ? ? } }
下面講一個(gè)如何使用自動實(shí)現(xiàn)的屬性實(shí)現(xiàn)輕量類:
此示例演示如何創(chuàng)建一個(gè)不可變輕量類,用于僅封裝一組自動實(shí)現(xiàn)的屬性。當(dāng)您必須使用引用類型語義時(shí),請使用此種構(gòu)造而不是結(jié)構(gòu)。
請注意:對于自動實(shí)現(xiàn)的屬性,需要 get 和 set 訪問器。 要使該類不可變,請將 set 訪問器聲明為 private。 但是,聲明私有 set 訪問器時(shí),不能使用對象初始值來初始化屬性。
下面的示例演示兩種方法來實(shí)現(xiàn)具有自動實(shí)現(xiàn)屬性的不可變類。第一個(gè)類使用構(gòu)造函數(shù)初始化屬性,第二個(gè)類使用靜態(tài)工廠方法。
class Contact ? ? ? { ? ? ? ? ? // Read-only properties. ? ? ? ? ? public string Name { get; private set; } ? ? ? ? ? public string Address { get; private set; } ? ? ? ? ? // Public constructor. ? ? ? ? ? public Contact(string contactName, string contactAddress) ? ? ? ? ? { ? ? ? ? ? ? ? Name = contactName; ? ? ? ? ? ? ? Address = contactAddress; ? ? ? ? ? ? ?? ? ? ? ? ? } ? ? ? } ? ? ? // This class is immutable. After an object is created, ? ? ? // it cannot be modified from outside the class. It uses a ? ? ? // static method and private constructor to initialize its properties. ?? ? ? ? public class Contact2 ? ? ? { ? ? ? ? ? // Read-only properties. ? ? ? ? ? public string Name { get; private set; } ? ? ? ? ? public string Address { get; private set; } ? ? ? ? ? // Private constructor. ? ? ? ? ? private Contact2(string contactName, string contactAddress) ? ? ? ? ? { ? ? ? ? ? ? ? Name = contactName; ? ? ? ? ? ? ? Address = contactAddress; ? ? ? ? ? ? ?? ? ? ? ? ? } ? ? ? ? ? // Public factory method. ? ? ? ? ? public static Contact2 CreateContact(string name, string address) ? ? ? ? ? { ? ? ? ? ? ? ? return new Contact2(name, address); ? ? ? ? ? } ? ? ? } ? ? ? public class Program ? ? ? {? ? ? ? ? ? static void Main() ? ? ? ? ? { ? ? ? ? ? ? ? // Some simple data sources. ? ? ? ? ? ? ? string[] names = {"Terry Adams","Fadi Fakhouri", "Hanying Feng",? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "Cesar Garcia", "Debra Garcia"}; ? ? ? ? ? ? ? string[] addresses = {"123 Main St.", "345 Cypress Ave.", "678 1st Ave", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "12 108th St.", "89 E. 42nd St."}; ? ? ? ? ? ? ? // Simple query to demonstrate object creation in select clause. ? ? ? ? ? ? ? // Create Contact objects by using a constructor. ? ? ? ? ? ? ? var query1 = from i in Enumerable.Range(0, 5) ? ? ? ? ? ? ? ? ? ? ? ? ? select new Contact(names[i], addresses[i]); ? ? ? ? ? ? ? // List elements cannot be modified by client code. ? ? ? ? ? ? ? var list = query1.ToList(); ? ? ? ? ? ? ? foreach (var contact in list) ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? Console.WriteLine("{0}, {1}", contact.Name, contact.Address); ? ? ? ? ? ? ? } ? ? ? ? ? ? ? // Create Contact2 objects by using a static factory method. ? ? ? ? ? ? ? var query2 = from i in Enumerable.Range(0, 5) ? ? ? ? ? ? ? ? ? ? ? ? ? ?select Contact2.CreateContact(names[i], addresses[i]); ? ? ? ? ? ? ? // Console output is identical to query1. ? ? ? ? ? ? ? var list2 = query2.ToList(); ? ? ? ? ? ? ? // List elements cannot be modified by client code. ? ? ? ? ? ? ? // CS0272: ? ? ? ? ? ? ? // list2[0].Name = "Eugene Zabokritski";? ? ? ? ? ? ? ? // Keep the console open in debug mode. ? ? ? ? ? ? ? Console.WriteLine("Press any key to exit."); ? ? ? ? ? ? ? Console.ReadKey(); ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? } ? /* Output: ? ? Terry Adams, 123 Main St. ? ? Fadi Fakhouri, 345 Cypress Ave. ? ? Hanying Feng, 678 1st Ave ? ? Cesar Garcia, 12 108th St. ? ? Debra Garcia, 89 E. 42nd St. */
上訴中,通過get存取器和set存取器將封裝好的專有數(shù)據(jù)成員和共同屬性關(guān)聯(lián)起來。
此時(shí),value關(guān)鍵字是時(shí)候出場了。
在普通的C#程序中,一般不能通過常用的調(diào)試手段獲得value值傳遞的詳細(xì)過程,不能像C++中一樣跟蹤指針的變化情況。當(dāng)使用如下語句給屬性賦值:
Class ValueCollector{...}; ValueCollector newValue = new ValueCollector(); newValue.nValue = 10;
新對象newValue的私有數(shù)據(jù)成員_nValue通過屬性nValue的set方法由原來的1改變?yōu)?0;
賦值語句的右值通過隱式參數(shù)value進(jìn)入屬性set方法內(nèi),成功改變整型私有變量的值。
在這一過程中,value參數(shù)的類型是整型,與屬性的類型是一致的。當(dāng)屬性的類型改變?yōu)閏har,value參數(shù)的屬性也相應(yīng)的改變?yōu)樽址汀?/p>
這種參數(shù)類型的自動轉(zhuǎn)換時(shí)基于.NETFramework提供的類型轉(zhuǎn)換器而實(shí)現(xiàn)的,CLR將C#源代碼編譯成中間語言IL,在這種類匯編的高級機(jī)器語言中可以發(fā)現(xiàn)value參數(shù)的傳遞機(jī)制。
C#中屬性的定義
屬性的定義
定義結(jié)構(gòu):
public int MyIntProp{ ? ? get{ ? ? ? ? ? ? //get code ? ? ? ? } ? ? set{ ? ? ? ? ? ? //set code ? ? ? ? } ? ? }
- 定義屬性需要名字和類型。
- 屬性包含兩個(gè)塊:get塊和set塊。
- 訪問屬性和訪問字段一樣,當(dāng)取得屬性的值得時(shí)候,就會調(diào)用屬性中的get塊,因此get塊需要返回值,其返回值類型就是屬性的類型;當(dāng)我們?nèi)ソo屬性設(shè)置值得時(shí)候,就會調(diào)用屬性中的set塊,以此可以在set塊中通過value訪問到我們所設(shè)置的值。
eg:
//跟訪問字段的方式一樣 v1.MyIntProperty = 600; //對屬性設(shè)置值,自動調(diào)用set塊 int temp = v1.MyIntProperty //對屬性取值,自動調(diào)用get塊
需要注意的是,set方法和get方法可以不同時(shí)存在。
但是如果沒有g(shù)et塊,就不可以獲得取值;如果沒有set塊,就不能進(jìn)行設(shè)置值。
通過屬性訪問字段
一般而言,習(xí)慣于將字段設(shè)置為private,這樣外界就不能修改字段的值。這是我們可以通過定義屬性來設(shè)置字段和獲取字段的值。
eg:
private int age; public int Age{ //習(xí)慣字段小寫,屬性大寫 ? ? set{ ? ? ? ? if(value<0) return; ? //通過set值進(jìn)行一些校驗(yàn)的工作 ? ? ? ? age = value; ? ? ? ? } ? ? get{ ? ? ? ? return age; ? ? ? ? } ? ? }
設(shè)置屬性的只讀或者只寫
只讀
private string name; public string Name{ ? ? get{ ? ? ? ? ? ? return name; ? ? ? ? }
只寫
private string name; public string Name{ ? ? set{ ? ? ? ? ? ? name = value; ? ? ? ? }
屬性的訪問修飾符
//如果在get或set塊錢加上private,表示這個(gè)塊只能在類內(nèi)進(jìn)行調(diào)用 public float X{ ? ? private set { x = value;} ? ? ? get { return x;} public float X{ ? ? set { x = value;} ? ? ? private ?get { return x;} ?
自動實(shí)現(xiàn)的屬性
public int Age{set;get;} ? ?//編譯器會自動提供字段來存儲age -->等價(jià)于 public int Age{ ? ? set{ age = value;} ? ? get{ return age;}
總結(jié)一下,屬性就相當(dāng)于是一種帶有set和get方法的一個(gè)方法,而它與類中的字段的賦值和取值又是息息相關(guān)的。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C#使用SendMessage實(shí)現(xiàn)進(jìn)程間通信的方法
這篇文章主要介紹了C#使用SendMessage實(shí)現(xiàn)進(jìn)程間通信的方法,涉及C#中SendMessage方法的使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04如何用C#實(shí)現(xiàn)SAGA分布式事務(wù)
大家好,本篇文章主要講的是如何用C#實(shí)現(xiàn)SAGA分布式事務(wù),感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下2022-01-01關(guān)于C#連接SQL Server時(shí)提示用戶登錄失敗的解決方法
在用C#開發(fā)windows端程序并連接SQL Server時(shí)有可能會遇到數(shù)據(jù)庫登錄失敗的問題,下面小編給大家?guī)砹薈#連接SQL Server時(shí)提示用戶登錄失敗的解決方法,感興趣的朋友一起看看吧2021-11-11