zoukankan      html  css  js  c++  java
  • 学习《深入理解C#》—— 数据类型、排序和过滤 (第一章1.1---1.2)

    引言

    在开始看这本书之前看过一些技术博客,填补自己对于一些知识点的不足。无意中发现了《深入理解C#》这本书,本书主要探讨C# 2、C# 3和C# 4的细节与特性,所以做了一下阅读笔记,欢迎拍砖。

    目录

    C#1 中定义的产品类型

     1  public class Product
     2     {
     3         string name;
     4         public string Name
     5         {
     6             get { return name; }
     7         }
     8         decimal price;
     9         public decimal Price
    10         {
    11             get { return price; }
    12         }
    13         public Product(string name, decimal price)
    14         {
    15             this.name = name;
    16             this.price = price;
    17         }
    18         public static ArrayList GetSampleProducts()
    19         {
    20             ArrayList list = new ArrayList();
    21             list.Add(new Product("硬装芙蓉王", 25m));
    22             list.Add(new Product("精白沙", 9m));
    23             list.Add(new Product("软白沙", 5.5m));
    25 return list; 26 } 27 public override string ToString() 28 { 29 return string.Format("{0}:{1}", name, price); 30 } 31 }

    缺点:

    1. ArrayList没有提供内部有关编译时的信息。我们很有可能在GetSampleProducts方法中添加一个字符串到ArrayList中,因为ArrayList的Add方法中的参数是object,而编辑器并没有任何反应。
    2. 代码中提供了属性的取值方法,如果添加对应的赋值方法,那么赋值方法也必须是公共的方法。
    3. 创建属性的代码过于复杂。

    C#2 中的强类型集合

    因C#1中没有泛型,Product类中的静态方法GetSampleProducts,返回的是ArrayList类型,里面添加的元素只能是Product,而在C#2中的改变就是泛型。(新的内容用红色列出)

     1 public class Product
     2     {
     3         string name;
     4         public string Name
     5         {
     6             get { return name; }
     7             private set { name = value; }
     8         }
    10         decimal price;
    11         public decimal Price
    12         {
    13             get { return price; }
    14             private set { price = value; }
    15         }
    17         public Product(string name, decimal price)
    18         {
    19             Name = name;
    20             Price = price;
    21         }
    22         public static List<Product> GetSampleProducts()
    23         {
    24             List<Product> list = new List<Product>();
    25             list.Add(new Product("硬装芙蓉王", 25m));
    26             list.Add(new Product("精白沙", 9m));
    27             list.Add(new Product("软白沙", 5.5m));
    28             return list;
    29         }
    30         public override string ToString()
    31         {
    32             return string.Format("{0}:{1}", name, price);
    33         }
    34     }

    优点:

    1. 属性有了私有赋值方法,且可以在构造函数中使用这个赋值方法。
    2. List<Product>告知编辑器里面只能包含Product,试图将一个不同的类型添加到列表中,会造成编译时错误。并且在使用List<Product>时不需要转换结果的数据类型。

     针对C#1中的存在的局限性,C#2解决了原先存在的前两个问题。

    C#3 中自动实现的属性

    相对C#2而言,C#3引入了自动属性和集合初始化器。Product中的属性Name和Price,可以通过自动属性简化代码,而编译器最终生成的代码是一致的。

     1 public class Product
     2     {
     3         public string Name{ get; private set; }
     5         public decimal Price { get; private set; }
     6         Product() { }
     8         public Product(string name, decimal price)
     9         {
    10             Name = name;
    11             Price = price;
    12         }
    14         public static List<Product> GetSampleProducts()
    15         {
    16             return new List<Product>
    17             {
    18                 new Product("硬装芙蓉王", 25m),
    19                 new Product("精白沙", 9m),
    20                 new Product("软白沙", 5.5m)
    21             };
    22         }
    24         public override string ToString()
    25         {
    26             return string.Format("{0}:{1}", Name, Price);
    27         }
    28     }

     优点:

    1. 没有多余的变量与属性相关联,因为类中没有了name和price变量,在类中使用属性名称是相同的。增强了代码的一致性。
    2. 创建的数据列表的方式也截然不同。
    3. 有一个私有的无参构造函数,用于新的基于属性的初始化。

    C# 4 中的命名实参

     在C#4中引入了命名实参,所谓命名实参是指命名参数调用实参顺序可以和形参不同。

     1 public class Product
     2     {
     3         readonly string name;
     4         public string Name
     5         {
     6             get { return name; }
     7         }
     9         readonly decimal price;
    10         public decimal Price
    11         {
    12             get { return price; }
    13         }
    15         public Product(string name, decimal price)
    16         {
    17             this.name = name;
    18             this.price = price;
    19         }
    20         public static List<Product> GetSampleProducts()
    21         {
    22             List<Product> list = new List<Product>();
    23             list.Add(new Product(name: "硬装芙蓉王", price: 25m));
    24             list.Add(new Product(name: "精白沙", price: 9m));
    25             list.Add(new Product(name: "软白沙", price: 5.5m));
    26             return list;
    27         }
    28         public override string ToString()
    29         {
    30             return string.Format("{0}:{1}", name, price);
    31         }
    32     }

    按名称对产品进行排序

    列表排序最简单的方式就是先将列表排好序,然后遍历并显示其中的项。在上述代码C# 1中,Product类中的静态方法GetSampleProducts,返回的是ArrayList类型,我们要求使用 ArrayList.Sort,要求提供一个IComparer实现。实现代码如下:

    1  public class ProductNameComparer : IComparer
    2     {
    3         public int Compare(object x, object y)
    4         {
    5             Product i = (Product)x;
    6             Product j = (Product)y;
    7             return i.Name.CompareTo(j.Name);
    8         }
    9     }
     1  static void Main(string[] args)
     2         {
     3             ArrayList arraylist = Product.GetSampleProducts();
     4             arraylist.Sort(new ProductNameComparer());
     5             foreach(Product pr in arraylist)
     6             {
     7                 Console.WriteLine(pr.Name);
     8             }
     9             Console.Read();
    10         }

     缺点:

    1. 必须引入额外的类型来帮助排序。
    2. Compare 方法中的强制类型转换。
    3. 假如ArrayList包含一个字符串货其他类型,那么代码会出错——因为在比较时会将字符串强制转型为 Product 。 
    4. foreach 循环会隐式将列表中的每个元素转换为 Product 类型,如果其中包含字符串或其他类型,同样会报错。

    然后在C#2中引入泛型了可以帮助我们解决上述问题。

    1 public class ProductNameComparer : IComparer<Product>
    2     {
    3         public int Compare(Product x, Product y)
    4         {
    5             return x.Name.CompareTo(y.Name);
    6         }
    7     }
     1  static void Main(string[] args)
     2         {
     3             List<Product> arraylist = Product.GetSampleProducts();
     4             arraylist.Sort(new ProductNameComparer());
     5             foreach(Product pr in arraylist)
     6             {
     7                 Console.WriteLine(pr.Name);
     8             }
     9             Console.Read();
    10         }

     优点:

    1. 开始提供的就是 Product(而不可能是其他类型),在Compare方法中不需要进行强制类型转换。
    2. foreach也不用隐式的类型转换。

    如果我们不希望引入额外的类型来帮助排序,而是直接对列表排序。C#2使用委托来排序。代码如下:

     1 static void Main(string[] args)
     2         {
     3             List<Product> arraylist = Product.GetSampleProducts();
     4             arraylist.Sort(delegate(Product x, Product y)
     5             {
     6                 return x.Name.CompareTo(y.Name);
     7             });
     8             foreach (Product pr in arraylist)
     9             {
    10                 Console.WriteLine(pr.Name);
    11             }
    12 13

    C#3 可以将匿名方法替换成Lambda表达式的方式进行排序。 

     1 static void Main(string[] args)
     2         {
     3             List<Product> arraylist = Product.GetSampleProducts();
     4             arraylist.Sort((x, y) => x.Name.CompareTo(y.Name));
     5             foreach (Product pr in arraylist)
     6             {
     7                 Console.WriteLine(pr.Name);
     8             }
     9             Console.Read();
    10         }

     C#3 使用扩展方法进行排序。 

    1 static void Main(string[] args)
    2         {
    3             List<Product> arraylist = Product.GetSampleProducts();
    4             foreach (Product pr in arraylist.OrderBy(p => p.Name))
    5             {
    6                 Console.WriteLine(pr.Name);
    7             }
    8             Console.Read();
    9         }

     

    查询集合

    查找集合中符合条件的所有元素,是一件很简单的事情,我们来一起来看C#1、C#2、C#之间查询集合的不同。

    现要求查找价格大于20的产品信息。

    C#1代码:

     1 static void Main(string[] args)
     2         {
     3             ArrayList arraylist = Product.GetSampleProducts();
     4             foreach (Product pr in arraylist)
     5             {
     6                 if (pr.Price > 20)
     7                 {
     8                     Console.WriteLine(pr);
     9                 }
    10             }
    11             Console.Read();
    12         }

     C#2代码:

     1 static void Main(string[] args)
     2         {
     3             List<Product> list = Product.GetSampleProducts();
     4             Predicate<Product> test = delegate(Product p) //设定查询条件
     5             {
     6                 return p.Price > 20;
     7             };
     8             List<Product> all = list.FindAll(test);      //查询所有价格大于20的产品,并保存到all中
     9             Action<Product> pro = Console.WriteLine;     //输出产品信息
    10             all.ForEach(pro); //循环输出产品信息
    11             Console.Read();
    12         }

     C#2另外一个版本代码:

    1 static void Main(string[] args)
    2         {
    3             List<Product> list = Product.GetSampleProducts();
    4             list.FindAll(delegate(Product p) //设定查询条件
    5             {
    6                 return p.Price > 20;
    7             }).ForEach(Console.WriteLine);
    8             Console.Read();
    9         }

     C#3代码:

    1 static void Main(string[] args)
    2         {
    3             List<Product> list = Product.GetSampleProducts();
    4             list.FindAll(p => { return p.Price > 20; }).ForEach(Console.WriteLine);
    5             Console.Read();
    6         }
    1 static void Main(string[] args)
    2         {
    3             List<Product> list = Product.GetSampleProducts();
    4             foreach (Product pro in list.Where(p => p.Price > 20))
    5             {
    6                 Console.WriteLine(pro);
    7             }
    8             Console.Read();
    9         }

    这篇就写到这里。下篇我们将继续学习《深入理解C#》的相关知识。

  • 相关阅读:
    使用BeyondCompare作为Subversive的比较器
    Ubuntu下安装jdk6的方法和步骤
    推荐几款通用的数据库管理工具
    通用数据库都有哪些
    Linux下卸载ORACLE的多种方法(参考使用)
    jar包查询网站 非常好用!
    8种Nosql数据库系统对比
    SQL2005数据库镜像的步骤
    建立与删除SQL 2008事务复制发布
    同步复制JOB说明
  • 原文地址:https://www.cnblogs.com/liujie2272/p/6545549.html
Copyright © 2011-2022 走看看