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

相关文章
相关标签/搜索