C#3.0新增功能01 自動實現的屬性

在 C# 3.0 及更高版本,當屬性訪問器中不須要任何其餘邏輯時,自動實現的屬性會使屬性聲明更加簡潔。 它們還容許客戶端代碼建立對象。 當你聲明如下示例中所示的屬性時,編譯器將建立僅能夠經過該屬性的 get 和 set 訪問器訪問的專用、匿名支持字段。html

下列示例演示一個簡單的類,它具備某些自動實現的屬性:函數

// 該類是可變的。它的數據能夠從類外部修改
class Customer
{
    // 用於普通get和set的自動實現屬性
    public double TotalPurchases { get; set; }
    public string Name { get; set; }
    public int CustomerID { get; set; }

    // 構造函數
    public Customer(double purchases, string name, int ID)
    {
        TotalPurchases = purchases;
        Name = name;
        CustomerID = ID;
    }

    // 方法
    public string GetContactInfo() { return "ContactInfo"; }
    public string GetTransactionHistory() { return "History"; }

    // 其餘的方法、事件等
}

class Program
{
    static void Main()
    {
        // 初始化一個新對象
        Customer cust1 = new Customer(4987.63, "Northwind", 90108);

        // 修改屬性
        cust1.TotalPurchases += 499.99;
    }
}

在 C# 6 和更高版本中,你能夠像字段同樣初始化自動實現屬性:spa

public string FirstName { get; set; } = "Jane";

上一示例中所示的類是可變的。 建立客戶端代碼後能夠用於更改對象中的值。 在包含重要行爲(方法)以及數據的複雜類中,一般有必要具備公共屬性。 可是,對於較小類或僅封裝一組值(數據)且只有不多行爲或沒有行爲的結構,則應該經過聲明 set 訪問器爲專用(對使用者的不可變)或經過聲明僅一個 get 訪問器(除構造函數外都不可變),使對象不可變。調試

使用自動實現的屬性實現輕量類

本示例演示如何建立一個僅用於封裝一組自動實現的屬性的不可變輕型類。 當你必須使用引用類型語義時,請使用此種構造而不是結構。code

可經過兩種方法來實現不可變的屬性:htm

  • 能夠將 set 訪問器聲明爲專用。 屬性只能在該類型中設置,但它對於使用者是不可變的。對象

    當你聲明一個 private set 取值函數時,你沒法使用對象初始值設定項來初始化屬性。你必須使用構造函數或工廠方法。blog

  • 也能夠僅聲明 get 訪問器,使屬性除了能在該類型的構造函數中可變,在其餘任何位置都不可變。事件

下面的示例演示了實現具備自動實現屬性的不可變類的兩種方法。 這兩種方法均使用 private set 聲明其中一個屬性,使用單獨的 get 聲明另外一個屬性。 第一個類僅使用構造函數來初始化屬性,第二個類則使用可調用構造函數的靜態工廠方法。ci

 1 // 這個類是不可變的。建立對象後,不能從類外部修改它。它使用構造函數初始化其屬性。
 2 class Contact
 3 {
 4     // 公共只讀屬性
 5     public string Name { get; }
 6     public string Address { get; private set; }
 7 
 8     // 公共構造函數
 9     public Contact(string contactName, string contactAddress)
10     {
11         Name = contactName;
12         Address = contactAddress;
13     }
14 }
15 
16 // 這個類是不可變的。建立對象後,不能從類外部修改它。它使用靜態方法和私有構造函數初始化其屬性。
17 public class Contact2
18 {
19     // 公共只讀屬性
20     public string Name { get; private set; }
21     public string Address { get; }
22 
23     // 私有構造函數
24     private Contact2(string contactName, string contactAddress)
25     {
26         Name = contactName;
27         Address = contactAddress;
28     }
29 
30     // 共有工廠方法
31     public static Contact2 CreateContact(string name, string address)
32     {
33         return new Contact2(name, address);
34     }
35 }
36 
37 public class Program
38 {
39     static void Main()
40     {
41         string[] names = {"Terry Adams","Fadi Fakhouri", "Hanying Feng",
42                           "Cesar Garcia", "Debra Garcia"};
43         string[] addresses = {"123 Main St.", "345 Cypress Ave.", "678 1st Ave",
44                               "12 108th St.", "89 E. 42nd St."};
45 
46         // 在 select 子句中演示對象建立的簡單查詢。使用構造函數建立contact對象。
47         var query1 = from i in Enumerable.Range(0, 5)
48                      select new Contact(names[i], addresses[i]);
49 
50         // 列表元素不能由客戶端代碼修改。
51         var list = query1.ToList();
52         foreach (var contact in list)
53         {
54             Console.WriteLine("{0}, {1}", contact.Name, contact.Address);
55         }
56 
57         // 使用靜態工廠方法建立contact2對象。
58         var query2 = from i in Enumerable.Range(0, 5)
59                      select Contact2.CreateContact(names[i], addresses[i]);
60 
61         // 控制檯輸出與query1相同。
62         var list2 = query2.ToList();
63 
64         // 列表元素不能由客戶端代碼修改。
65         // CS0272:
66         // list2[0].Name = "Eugene Zabokritski";
67 
68         // 在調試模式下保持控制檯打開。
69         Console.WriteLine("Press any key to exit.");
70         Console.ReadKey();
71     }
72 }
73 
74 /* 輸出:
75     Terry Adams, 123 Main St.
76     Fadi Fakhouri, 345 Cypress Ave.
77     Hanying Feng, 678 1st Ave
78     Cesar Garcia, 12 108th St.
79     Debra Garcia, 89 E. 42nd St.
80 */

編譯器爲每一個自動實現的屬性建立了支持字段。 這些字段沒法直接從源代碼進行訪問。

 

相關文章
相關標籤/搜索