• C#开发的进化史(从简单数据开始)


    本次讲解的是C#开发的进化史--从简单数据类型开始

    一.C#1定义的产品类型

      我们将以定义一个表示产品的类型作为开始,然后进行处理。在Product类的内部,没有特别吸引人的东西,它只是封装了几个属性。还要定义在这个地方创建预定义产品的一个列表

    代码:

    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中的三个局限:

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

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

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

    二、C#2的强类型集合

       根据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。试图将一个不同的类型添加到列表中,会造成编译器时错误,并且当你从列表中获取结果时,也并不需要转换结果类型。

    三、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变量可供访问,我们必须在类中处处使用属性,这增强了一致性。现在有一个私有的无参构造函数,用于新的基于属性的初始化。(设置这些属性之前会对每一项调用这个构造函数。)

          实际上可以完全删除旧的公共构造函数。但这样依赖,外部代码就不能在创建其他的产品实例了

    四、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最重要的一部分,但是,现在只是看到了它的部分用处。

  • 相关阅读:
    Python Post四种请求方式
    Python 字符串转Base64编解码
    JS 数组遍历
    FineUI MVC 前端获取表格Json通过Post传递后台
    C# Json转DataTable
    MSSQL 关联更新
    Python selenium Message: session not created: This version of ChromeDriver only supports Chrome version 76
    FineUI MVC 同级新增页签
    Tomcat Tomcat的中文乱码设置
    zabbix-4.0-监控服务器的ping告警设置
  • 原文地址:https://www.cnblogs.com/jiangyu-zhoujie/p/9035647.html
Copyright © 2020-2023  润新知