一个产品(Product)类,通过该类的声明来观察C#的进化
C# 1.0版
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("Company", 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.0 存在下面4种局限性
1、ArrayList没有提供与内部内容有关的编译时信息。
导致的问题:完全可能不慎在GetSampleProducts 创建的列表中添加一个字符串,而编译器对此没有任何的反应。
理解:即list.Add("杂类数据"); 如果在函数中增加上面的语句,编译器不会报错,但对于该类来说,list中Add的此类数据会造成运行时错误。
2、代码中为属性提供了公共的取值方法,这意味着如果添加对应的赋值方法,那么赋值方法也必须是公共的。
导致的问题:如果需要提供一个校验机制,每次设置一个值之后都进行校验,此种情况下,会使用属性赋值,但现在属性是公共,而要求不能把它们暴露给外部世界,所以不得不创建一个私有的SetPrice方法或者其他类似的方法,不方便。
理解:根据和C#2.0,3.0的比较,此处的意思为不能给属性的set方法增加私有属性。
【不解:属性的私有赋值方法有何作用?】
3、变量本身可由类的其余部分使用。最好能封装到属性中,确定它们只能通过属性来修改对应的值。
理解:name,price 两个变量类的其他代码也能访问到,同时又可访问Name,Price属性,容易混乱,不一致。
4、用于创建属性和变量的代码很复杂。【这个……】
C#2.0版Product类声明如下:
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<Product> GetSampleProducts() { List<Product> list = new List<Product>(); list.Add(new Product("Company", 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.0对此类的改动量不大,但有效的解决了1.0的2个局限性,如下描述:
1、属性有了私有的赋值方法。【再次不解:私有赋值有何用处?】
2、GetSampleProducts 函数能非常“聪明”地猜出List<Product>是告知编译器列表中只能包含Product。
理解:即上述代码中list对象中只能Add Product对象,如果list.Add("杂类数据"),编译器会编译时会报错。
C#3.0 版Product类如下:
public class Product { public string Name { get; private set; } public decimal Price { get; private set; } public Product(string name, decimal price) { Name= name; Price= price; } Product() { } public static List<Product> GetSampleProducts() { return new List<Product> { new Product{Name="Company",Price=9.99m}, new Product{Name="Assassins",Price=14.99m}, new Product{Name="Frogs",Price=13.99m}, new Product{Name="Sweeney Todd",Price=10.99m} }; } public override string ToString() { return string.Format("{0}:{1}", Name, Price); } }
据书中所述,C#3.0优势如下:
1、不再有任何代码(或者可见的变量)与属性关联【指的是2.0和1.0中的私有变量name和price?】
2、硬编码的列表完全用不同的方式来构建(指 GetSampleProducts函数)
3、去掉了name和price变量,使得在类中处处适用属性,增强了一致性。
4、存在一个私有的无参数构造函数,用于新的基于属性的初始化。【此话何解?】
后记:
1、此处记录采用书中原话记录(翻译后版本),部分无法理解,做备份,慢慢理解。
2、通过3个版本代码的对比,优化个人代码编写习惯。