【已更新最新开发文章,点击查看详细】
当你声明以下示例中所示的属性时,编译器将创建仅可以通过该属性的 get 和 set 访问器访问的专用、匿名支持字段。
下列示例演示一个简单的类,它具有某些自动实现的属性:
// 该类是可变的。它的数据可以从类外部修改 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 和更高版本中,你可以像字段一样初始化自动实现属性:
public string FirstName { get; set; } = "Jane";
专用(对使用者的不可变)或通过声明仅一个 get 访问器(除构造函数外都不可变),使对象不可变。
使用自动实现的属性实现轻量类
当你必须使用引用类型语义时,请使用此种构造而不是结构。
可通过两种方法来实现不可变的属性:
-
属性只能在该类型中设置,但它对于使用者是不可变的。
你必须使用构造函数或工厂方法。
-
get 访问器,使属性除了能在该类型的构造函数中可变,在其他任何位置都不可变。
第一个类仅使用构造函数来初始化属性,第二个类则使用可调用构造函数的静态工厂方法。
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 */
这些字段无法直接从源代码进行访问。
【已更新最新开发文章,点击查看详细】