【第一章】C#的进化史——C#1.0,2.0,3.0区别比较(一)

时间:2022-04-27 19:06:35

一个产品(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、存在一个私有的无参数构造函数,用于新的基于属性的初始化。【此话何解?】

【第一章】C#的进化史——C#1.0,2.0,3.0区别比较(一)


后记:

1、此处记录采用书中原话记录(翻译后版本),部分无法理解,做备份,慢慢理解。

2、通过3个版本代码的对比,优化个人代码编写习惯。