Generic List Sorting in C# 3.0
前一篇【Generic List<T> Sorting】主要是針對 C# 2.0 的時代,講解如何從無到有自繼承 IComparable<Product> 介面,並實作 CompareTo 方法來定義物件的排序方法;繼承 IComparer<T> 介面,實作 Compare 方法定義排序欄位與排序順序(ASC 與 DESC)。不過,發表該篇文章以後迴響卻不如預期?因為,這樣的方法在 C# 3.0 是非常不必要的。以下的範例,就利用 C# 3.0 的八大新功能,來實作 C# 3.0 中 Generic List
首先,C# 3.0 八大新功能 ,如下:
- Implicitly Typed Local Variables and Arrays
- Object Initializers
- Collection Initializers
- Anonymous Types
- Lambda Expressions
- Extension Methods
- Auto-Implemented Properties
- Partial Method Definitions
參閱 :
其中 2 3 7 我在【C# 3.0 - Object And Collection Initializers】該篇文章有提到,6 有【C# 3.0 - Extension Methods 練習】介紹,而接下來 C# 3.0 Generic List
(1) 建立 Product 類別作為示範,該類別擁有 int 型態的 ID 屬性、string 型態的 Name 屬性、double 型態的 Pricce 屬性、DateTime 型態的 ShipDate 屬性,覆寫 ToString() 方法方便我們列印。(使用到 7 Auto-Implemented Properties 新功能)
1: public class Product
2: {
3: public int ID { get; set; }
4: public string Name { get; set; }
5: public double Price { get; set; }
6: public DateTime ShipDate { get; set; }
7:
8: public override string ToString()
9: {
10: return string.Format("ID: {0}, Name: {1}, Price: {2}, ShipDate: {3}", ID, Name, Price, ShipDate.ToShortDateString());
11: }
12: }
(2) 其實,準備工作在上一步就完全結束了,以下就實際操作範例,首先建立 List<Product> 當作我們測試的範例。(該步驟包含 1 Implicitly Typed Local Variables and Arrays、 2 Object Initializers 、3 Collection Initializers)
1: var pList = new List<Product>
2: {
3: new Product {ID = 1, Name = "A", Price = 7, ShipDate = new DateTime(2006, 1, 19)},
4: new Product {ID = 7, Name = "C", Price = 237, ShipDate = new DateTime(2006, 10, 17)},
5: new Product {ID = 4, Name = "B", Price = 17, ShipDate = new DateTime(2007, 2, 12)},
6: new Product {ID = 5, Name = "D", Price = 57, ShipDate = new DateTime(2005, 9, 11)}
7: };
(3) 只要有繼承 IEnumerable 介面或是 IEnumerable<T> 介面,現在都內建 OrderBy 與 OrderByDescending 的 Extension Methods 新功能,以下就是利用 .Net Framework 內建的 Extension Methods 來針對【屬性排序】與【排序順序】。
1: // 依照 ID 欄位,升冪排序
2: foreach (var product in pList.OrderBy(p => p.ID))
3: {
4: Console.WriteLine(product.ToString());
5: }
6: Console.WriteLine();
7:
8: // 依照 Name 欄位,降冪排序
9: foreach (var product in pList.OrderByDescending(p => p.Name))
10: {
11: Console.WriteLine(product.ToString());
12: }
13: Console.WriteLine();
14:
15: // 依照 Price 欄位,降冪排序
16: foreach (var product in pList.OrderByDescending(p => p.Price))
17: {
18: Console.WriteLine(product.ToString());
19: }
20: Console.WriteLine();
21:
22: // 依照 ShipDate 欄位,升冪排序
23: foreach (var product in pList.OrderBy(p => p.ShipDate))
24: {
25: Console.WriteLine(product.ToString());
26: }
以上範例,可以看到升冪排序我們使用 Orderby 方法;降冪排序則使用 OrderByDescending 方法。其中,方法參數中 p => p.ID 則是一種 Lambda Expression 告知方法,我們指定排序的欄位。而在 foreach 迴圈,我們使用 var product 來讓程式自動推斷 product 的型別,然後利用 Product 類別的 ToString 方法,將詳細內容印出。 (使用 1 Implicitly Typed Local Variables and Arrays、5 Lambda Expressions、6 Extension Methods )
輸出結果:
1: // 依照 ID 欄位,升冪排序
2: ID: 1, Name: A, Price: 7, ShipDate: 2006/1/19
3: ID: 4, Name: B, Price: 17, ShipDate: 2007/2/12
4: ID: 5, Name: D, Price: 57, ShipDate: 2005/9/11
5: ID: 7, Name: C, Price: 237, ShipDate: 2006/10/17
6:
7: // 依照 Name 欄位,降冪排序
8: ID: 5, Name: D, Price: 57, ShipDate: 2005/9/11
9: ID: 7, Name: C, Price: 237, ShipDate: 2006/10/17
10: ID: 4, Name: B, Price: 17, ShipDate: 2007/2/12
11: ID: 1, Name: A, Price: 7, ShipDate: 2006/1/19
12:
13: // 依照 Price 欄位,降冪排序
14: ID: 7, Name: C, Price: 237, ShipDate: 2006/10/17
15: ID: 5, Name: D, Price: 57, ShipDate: 2005/9/11
16: ID: 4, Name: B, Price: 17, ShipDate: 2007/2/12
17: ID: 1, Name: A, Price: 7, ShipDate: 2006/1/19
18:
19: // 依照 ShipDate 欄位,升冪排序
20: ID: 5, Name: D, Price: 57, ShipDate: 2005/9/11
21: ID: 1, Name: A, Price: 7, ShipDate: 2006/1/19
22: ID: 7, Name: C, Price: 237, ShipDate: 2006/10/17
23: ID: 4, Name: B, Price: 17, ShipDate: 2007/2/12