热线(9:00-18:00):13544706711
当前位置: 首页 > 教程技巧 > 

学习《深入理解C#》—— 数据类型、排序和过滤 (第一章1.1---1.2)

时间: 2017/03/16 06:47:12

引言


在开始看这本书之前看过一些技术博客,填补自己对于一些知识点的不足。无意中发现了《深入理解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 GetSampleProducts()
23 {
24 List list = new List();
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,试图将一个不同的类型添加到列表中,会造成编译时错误。并且在使用List时不需要转换结果的数据类型。


 针对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 GetSampleProducts()
15 {
16 return new List
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 GetSampleProducts()
21 {
22 List list = new List();
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
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 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 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 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 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 list = Product.GetSampleProducts();
4 Predicate test = delegate(Product p) //设定查询条件
5 {
6 return p.Price > 20;
7 };
8 List all = list.FindAll(test); //查询所有价格大于20的产品,并保存到all中
9 Action pro = Console.WriteLine; //输出产品信息
10 all.ForEach(pro); //循环输出产品信息
11 Console.Read();
12 }


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



1 static void Main(string[] args)
2 {
3 List 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 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 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#》的相关知识。