本次講解的是C#開發的進化史--從簡單數據類型開始sass
一.C#1定義的產品類型ide
咱們將以定義一個表示產品的類型做爲開始,而後進行處理。在Product類的內部,沒有特別吸引人的東西,它只是封裝了幾個屬性。還要定義在這個地方建立預約義產品的一個列表函數
代碼:this
using System.Collections; public class Product { readonly string name; public string Name { get { return name; } } readonly decimal price; public decimal Price { get { return price; } } /// <summary> /// 構造函數 /// </summary> /// <param name="name"></param> /// <param name="price"></param> public Product(string name, decimal price) { this.name = name; this.price = price; } public static ArrayList GetSanpleProducts() { ArrayList list = new ArrayList(); list.Add(new Product("West Side Story ", 9.99m)); list.Add(new Product("Assassins ", 14.99m)); list.Add(new Product("Frogs ", 13.99m)); list.Add(new Product("Sweeney Todd ", 10.99m)); return list; } public override string ToString() { return string.Format("{0} {1}", name, price); } }
在這段代碼中,暴露出C#1中的三個侷限:spa
1.ArrayList沒有提供與內部有關的編譯時的信息。不慎在GetSanpleProducts建立的列表中添加一個字符串是徹底有可能的,而編譯器對此沒有任何反應。orm
2.代碼中爲屬性提供了公共的取值方法,這意味着若是添加對應的賦值方法,那麼賦值方法也必須是公共的。對象
3.用於建立屬性和變量的代碼很複雜--封裝一個字符串和一個十進制數應該是一個十分簡單任務,不應這麼複雜。blog
2、C#2的強類型集合ci
根據C#1定義的產品類型侷限,列出的前兩項,在C#2進行解決。包含C#2最重要的改變:泛型。開發
強類型集合和私有的賦值方法
public class Product { string name; public string Name { get { return name; } private set { name = value; } } decimal price; public decimal Price { get { return price; } private set { price = value; } } /// <summary> /// 構造函數 /// </summary> /// <param name="name"></param> /// <param name="price"></param> public Product(string name, decimal price) { name = name; price = price; } public static List<Product> GetSanpleProducts() { List<Product> list = new List<Product>(); list.Add(new Product("West Side Story ", 9.99m)); list.Add(new Product("Assassins ", 14.99m)); list.Add(new Product("Frogs ", 13.99m)); list.Add(new Product("Sweeney Todd ", 10.99m)); return list; } public override string ToString() { return string.Format("{0} {1}", name, price); } }
屬性擁有了私有的賦值方法(咱們在構造函數中使用了這兩個賦值方法)。而且他能很是「聰明」地猜出List<Product>是告知編譯器列表只能包含Product。試圖將一個不一樣的類型添加到列表中,會形成編譯器時錯誤,而且當你從列表中獲取結果時,也並不須要轉換結果類型。
3、C#3中自動實現的屬性
在C#2中解決了C#1的三個問題中的前兩個問題,在C#3中將最後一個問題進行解決
自動實現的屬性和簡化的初始化,相比lambda表達式等特性來講,有點微不足道
自動實現的屬性和更簡單的初始化
public class Product { public string Name { get; private set; } public decimal Price { get; private set; } /// <summary> /// 構造函數 /// </summary> /// <param name="name"></param> /// <param name="price"></param> public Product(string name, decimal price) { this.Name = name; this.Price = price; } Product() { } public static List<Product> GetSanpleProducts() { return new List<Product> { new Product("West Side Story ", 9.99m), new Product("Assassins ", 14.99m), new Product("Frogs ", 13.99m), new Product("Sweeney Todd ", 10.99m) }; } public override string ToString() { return string.Format("{0} {1}", Name, Price); } }
再也不有任何代碼(或者可見的變量)與屬性關聯,並且硬代碼的列表是以一種全然不一樣的方式構建的。因爲沒有name和price變量可供訪問,咱們必須在類中到處使用屬性,這加強了一致性。如今有一個私有的無參構造函數,用於新的基於屬性的初始化。(設置這些屬性以前會對每一項調用這個構造函數。)
實際上能夠徹底刪除舊的公共構造函數。但這樣依賴,外部代碼就不能在建立其餘的產品實例了
4、C#4中命名實參
對於C#4,涉及屬性和構造函數時,咱們須要回到原始代碼。其實有一個緣由是爲了讓它不易變:儘管擁有私有賦值方法的類型不能被公共地改變,但若是它也不能被私有的改變(面向C#1的那段代碼原本也是不可變的,讓它可變是爲了簡化面向C#2和C#3的代碼段的修改),將會更加清晰。不幸的是,對只讀屬性,沒有快捷方式。但C#4容許咱們在構造是指定實參的名稱,它提供了和C#3的初始化程序同樣的清晰度,並且還移除了易變性。
命名實參來了清晰的初始化代碼
public class Product { readonly string name; public string Name { get { return name; } } readonly decimal price; public decimal Price { get { return price; } } readonly int supplierId; public int SupplierId { get { return supplierId; } } /// <summary> /// 構造函數 /// </summary> /// <param name="name"></param> /// <param name="price"></param> public Product(string name, decimal price,int supplierId) { this.name = name; this.price = price; this.supplierId = supplierId; } Product() { } public static List<Product> GetSanpleProducts() { return new List<Product> { new Product(name:"West Side Story ", price:9.99m,supplierId:1), new Product(name:"Assassins ", price:14.99m,supplierId:2), new Product(name:"Frogs ", price:13.99m,supplierId:3), new Product(name:"Sweeney Todd ", price:10.99m,supplierId:4) }; } public override string ToString() { return string.Format("{0} {1}", Name, Price); } }
在這個特定的示例中,該特性的好處不是很明顯,但當方法或構造函數包含多個參數時,他可使代碼含義更加清楚——特別是當參數類型相同,或某個參數爲null時。
總結:
product類型的演變歷程,展現了愈來愈好的封裝性、愈來愈強類型化以及愈來愈容易的初始化
1.C#1:只讀屬性弱類型集合
2.C#2:私有屬性賦值方法,強類型集合
3.C#3:自動實現的屬性、加強的集合和對象初始化
4.C#4:用命名實參更清晰地調用構造函數和方法
到目前爲止,你看到的變化幅度都不大。事實上,泛型的加入或許是C#2最重要的一部分,可是,如今只是看到了它的部分用處。