C#開發的進化史(從簡單數據開始)

本次講解的是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最重要的一部分,可是,如今只是看到了它的部分用處。

相關文章
相關標籤/搜索