在 C# 3.0 及更高版本,當屬性訪問器中不需要任何其他邏輯時,自動實現的屬性會使屬性聲明更加簡潔。它們還允許客戶端代碼創建對象。當你聲明以下示例中所示的屬性時,編譯器將創建僅可以通過該屬性的 get 和 set 訪問器訪問的專用、匿名支持字段。
下列示例演示一個簡單的類,它具有某些自動實現的屬性:
// This class is mutable. Its data can be modified from// outside the class.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; }}
在 C# 6 和更高版本中,你可以像字段一樣初始化自動實現屬性:
public string FirstName { get; set; } = "Jane";
上一示例中所示的類是可變的。創建客戶端代碼后可以用于更改對象中的值。在包含重要行為(方法)以及數據的復雜類中,通常有必要具有公共屬性。但是,對于較小類或僅封裝一組值(數據)且只有很少行為或沒有行為的結構,則應該通過聲明 set 訪問器為 專用(對使用者的不可變)或通過聲明僅一個 get 訪問器 (除構造函數外都不可變),使對象不可變。
動實現的屬性上允許使用特性,但很明顯支持字段上不允許,因為不能從你的源代碼訪問它們。如果必須使用屬性的支持字段上的特性,只需創建一個常規屬性。
使用自動實現的屬性實現輕量類
本示例演示如何創建一個僅用于封裝一組自動實現的屬性的不可變輕型類。 當你必須使用引用類型語義時,請使用此種構造而不是結構。
可通過兩種方法來實現不可變的屬性。 可以將 set 取值函數聲明為 private。 屬性只能在該類型中設置,但它對于使用者是不可變的。 也可以僅聲明 get 取值函數,使屬性除了能在該類型的構造函數中設置,在其他任何位置都不可變。
當你聲明一個 private set 取值函數時,你無法使用對象初始值設定項來初始化屬性。 你必須使用構造函數或工廠方法。
示例
下面的示例演示了實現具有自動實現屬性的不可變類的兩種方法。 這兩種方法均使用 private set 聲明其中一個屬性,使用單獨的 get 聲明另一個屬性。 第一個類僅使用構造函數來初始化屬性,第二個類則使用可調用構造函數的靜態工廠方法。
// This class is immutable. After an object is created, // it cannot be modified from outside the class. It uses a // constructor to initialize its properties. class Contact { // Read-only properties. public string Name { get; } 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 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(); } }
輸出:
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.
編譯器為每個自動實現的屬性創建了支持字段。 這些字段無法直接從源代碼進行訪問。
新聞熱點
疑難解答