第一章 C#开发的进化史:1.1从简单的数据类型开始

来源:互联网 发布:微博用户画像算法 编辑:程序博客网 时间:2024/05/13 13:54
1.1从简单的数据类型开始

//C#1:只读属性,弱类型集合using System.Collections;public class Product{    string name;        public string Name { get { return name; } }        decimal price;        public decimal Price { get { return price; } }        public Product(string name, decimal price)        {            this.name = name;            this.price = price;        }        public static ArrayList GetSampleProducts()        {            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));            list.Add("我添加了一个无关的字符串,编译器却那我没有办法!!!");            return list;        }        public override string ToString()        {            return string.Format("{0}:{1}", name, price);        }    }}

C#1代码存在如下3个缺陷:

1.ArrayList没有提供与其内部内容有关的编译时信息。不慎在GetSampleProducts创建的列表中添加一个字符串是完全可能的,而编译器对于此没有任何反应。

2.代码中为属性提供了公共的取值方法,这意味着如果添加对应的赋值方法,那么赋值方法也必须是公共的。

3.用于创建属性和变量的代码很复杂——封装一个字符串和一个十进制数应该是一个十分简单的任务,不该这么复杂。


//C#2:私有属性赋值方法和强类型集合using System.Collections.Generic;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; }    }    public Product(string name, decimal price)    {        Name = name;        Price = price;    }    public static List GetSampleProducts()    {        List list = new List();        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#2中解决了上面3个缺陷中的前2个。
C#2中最重要的改变:泛型。
现在,属性拥有了私有的 赋值方法(只能类内使用,这里在构造函数中使用了这两个赋值方法)。并且它能非常聪明地猜出List<Product>是告知编译器列表中只能包含Product类型的值。试图将一个不同的类型添加到列表中,编译器就会报错,并且当你从列表中获取结果时,也不需要转换结果的类型,因为取出来的一定是Product类型的值。

//C#3:自动实现的属性、增强的集合和对象初始化using System.Collections.Generic;public class Product{     public string Name { get; private set; }        public decimal Price { get; private set; }                //旧的公共构造函数,可删除。(不过删除后外部代码就不能创建其他Product的实例了)        public Product(string name, decimal price)        {            Name = name;            Price = price;        }                //构造函数        Product() { }        public static List GetSampleProducts()        {            return new List            {                new Product { Name = "West Side Story", Price = 9.99m },                new Product { Name = "Assassins", Price = 14.99m },                new Product { Name = "Frogs", Price = 13.99m },                new Product { Name = "Sweeney", Price = 10.99m }            };        }        public override string ToString()        {            return string.Format("{0}:{1}", Name, Price);        }}
C#3解决了第3个缺陷,自动实现的属性和更简单的初始值,大大简化了代码。
现在,不再有任何代码(或者可见的变量)与属性关联,而且硬编码的列表是以一种全然不同的方式构建的。由于没有name和price变量可供访问,我们必须在类中处处使用属性,这增强了一致性。

//C#4:用命名实参更清晰地调用构造函数和方法using System.Collections.Generic;public class Product{    readonly string name;    public string Name { get { return name; } }    readonly decimal price;    public decimal Price { get { return price; } }    public Product(string name, decimal price)    {        //调用构造函数时指定实参的名称        this.name = name;        this.price = price;    }    public static List GetSampleProducts()    {        return new List        {            new Product ( name : "West Side Story", price : 9.99m ),            new Product ( name : "Assassins", price : 14.99m ),            new Product ( name : "Frogs", price : 13.99m ),            new Product ( name : "Sweeney", price : 10.99m )        };    }        public override string ToString()    {        return string.Format("{0}:{1}", name, price);    }}
C#4移除了易变性(mutability)。
尽管私有赋值方法的类型不能被公共地改变,但如果它也不能被私有地改变,将会显得更加清晰。不幸的是,对于只读属性,没有快捷方式。但C#4允许我们在调用构造函数的时候指定实参的名称。
当方法或构造函数包含多个参数时,特别是当参数类型相同或某个参数为null时,指定实参名称可以使代码的含义更加清楚。




0 0
原创粉丝点击