網站首頁 編程語言 正文
C#中的屬性(get、set、value)
C#語言在面向對象設計和編程中對數據安全提出了嚴格的要求,其中一個重要的原則就是數據封裝。根據這一原則,C#程序設計中要求開發人員對特定類的數據字段盡量不以公有方式提供給外界。因此在類內部多數字段的訪問權限被限定為private或是public,而這些字段與外界的交流經常采用屬性來進行。
屬性使類能夠以一種公開的方法獲取和設置值,同時隱藏實現或驗證代碼。
屬性是這樣的成員:它們提供靈活的機制來讀取、編寫或計算私有字段的值。
可以像使用公共數據成員一樣使用屬性,但實際上它們是稱作“訪問器”的特殊方法。這 使得可以輕松訪問數據,此外還有助于提高方法的安全性和靈活性。
屬性使類能夠以一種公開的方法獲取和設置值,同時隱藏實現或驗證代碼。
get 屬性訪問器用于返回屬性值,而 set 訪問器用于分配新值。 這些訪問器可以有不同的訪問級別。
get 訪問器體與方法體相似。 它必須返回屬性類型的值。執行 get 訪問器相當于讀取字段的值
get 訪問器必須以 return 或 throw 語句終止,并且控制權不能離開訪問器體。
value 關鍵字用于定義由 set 取值函數分配的值。
不實現 set 取值函數的屬性是只讀的。
屬性的定義通常由以下兩部分組成:
1、需要封裝的專用數據成員
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;
? ? }
}
當屬性的訪問器中不需要其他邏輯時,自動實現的屬性可使屬性聲明更加簡潔。客戶端還可以通過這些屬性創建對象,例如下面的代碼,編譯器將創建一個私有的匿名支持字段,該字段只能通過屬性的get和set訪問器進行訪問。
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;
? ? }
}
下面講一個如何使用自動實現的屬性實現輕量類:
此示例演示如何創建一個不可變輕量類,用于僅封裝一組自動實現的屬性。當您必須使用引用類型語義時,請使用此種構造而不是結構。
請注意:對于自動實現的屬性,需要 get 和 set 訪問器。 要使該類不可變,請將 set 訪問器聲明為 private。 但是,聲明私有 set 訪問器時,不能使用對象初始值來初始化屬性。
下面的示例演示兩種方法來實現具有自動實現屬性的不可變類。第一個類使用構造函數初始化屬性,第二個類使用靜態工廠方法。
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存取器將封裝好的專有數據成員和共同屬性關聯起來。
此時,value關鍵字是時候出場了。
在普通的C#程序中,一般不能通過常用的調試手段獲得value值傳遞的詳細過程,不能像C++中一樣跟蹤指針的變化情況。當使用如下語句給屬性賦值:
Class ValueCollector{...};
ValueCollector newValue = new ValueCollector();
newValue.nValue = 10;
新對象newValue的私有數據成員_nValue通過屬性nValue的set方法由原來的1改變為10;
賦值語句的右值通過隱式參數value進入屬性set方法內,成功改變整型私有變量的值。
在這一過程中,value參數的類型是整型,與屬性的類型是一致的。當屬性的類型改變為char,value參數的屬性也相應的改變為字符型。
這種參數類型的自動轉換時基于.NETFramework提供的類型轉換器而實現的,CLR將C#源代碼編譯成中間語言IL,在這種類匯編的高級機器語言中可以發現value參數的傳遞機制。
C#中屬性的定義
屬性的定義
定義結構:
public int MyIntProp{
? ? get{
? ? ? ? ? ? //get code
? ? ? ? }
? ? set{
? ? ? ? ? ? //set code
? ? ? ? }
? ? }
- 定義屬性需要名字和類型。
- 屬性包含兩個塊:get塊和set塊。
- 訪問屬性和訪問字段一樣,當取得屬性的值得時候,就會調用屬性中的get塊,因此get塊需要返回值,其返回值類型就是屬性的類型;當我們去給屬性設置值得時候,就會調用屬性中的set塊,以此可以在set塊中通過value訪問到我們所設置的值。
eg:
//跟訪問字段的方式一樣
v1.MyIntProperty = 600; //對屬性設置值,自動調用set塊
int temp = v1.MyIntProperty //對屬性取值,自動調用get塊
需要注意的是,set方法和get方法可以不同時存在。
但是如果沒有get塊,就不可以獲得取值;如果沒有set塊,就不能進行設置值。
通過屬性訪問字段
一般而言,習慣于將字段設置為private,這樣外界就不能修改字段的值。這是我們可以通過定義屬性來設置字段和獲取字段的值。
eg:
private int age;
public int Age{ //習慣字段小寫,屬性大寫
? ? set{
? ? ? ? if(value<0) return; ? //通過set值進行一些校驗的工作
? ? ? ? age = value;
? ? ? ? }
? ? get{
? ? ? ? return age;
? ? ? ? }
? ? }
設置屬性的只讀或者只寫
只讀
private string name;
public string Name{
? ? get{
? ? ? ? ? ? return name;
? ? ? ? }
只寫
private string name;
public string Name{
? ? set{
? ? ? ? ? ? name = value;
? ? ? ? }
屬性的訪問修飾符
//如果在get或set塊錢加上private,表示這個塊只能在類內進行調用
public float X{
? ? private set { x = value;} ?
? ? get { return x;}
public float X{
? ? set { x = value;} ?
? ? private ?get { return x;} ?
自動實現的屬性
public int Age{set;get;} ? ?//編譯器會自動提供字段來存儲age
-->等價于
public int Age{
? ? set{ age = value;}
? ? get{ return age;}
總結一下,屬性就相當于是一種帶有set和get方法的一個方法,而它與類中的字段的賦值和取值又是息息相關的。?
原文鏈接:https://dabaojian.blog.csdn.net/article/details/47832817
相關推薦
- 2022-06-04 Python?os和os.path模塊詳情_python
- 2023-07-08 qt修改默認構建路徑
- 2022-05-03 在Django中動態地過濾查詢集的實現_python
- 2021-12-05 Android?NDK開發(C語言-文件讀寫)_Android
- 2022-06-19 dockerfile指令構建docker鏡像的示例代碼_docker
- 2024-03-07 SpringAOP基于XML方式實現(了解)
- 2022-01-17 將字符串轉換成時間戳,yyyymmss到yyyy-mm-dd ,之后從時間戳轉換成時間格式字符串
- 2022-01-28 寶塔的定時任務,如何設置秒數級別執行?
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支