02.C#可空類型、默認參數、LINQ(一章1.3-1.4)

  利用上班時間發個隨筆,不知領導會不會看到,可能會有同事看到也說不定啊:)

  

  關于可空類型,在C#1中沒有這個概念,在C#3中引入的。那比如我們要實現一個表示人的類,人有名字和年齡兩個屬性,如何表示一個沒有年齡的人呢?

一般作法會將一人int類型封裝成一個引用類型,有人的類中使用成員屬性,該屬性的類型為剛封裝的引用類型,如下

 1 public class Person
 2     {
 3         private string name;
 4         private PersonAge age;
 5 
 6         public Person(string name, PersonAge age)
 7         {
 8             this.name = name;
 9             this.age = age;
10         }
11 
12     }
13 
14     //C#1中使用一個一個引用包裝器類
15 
16     public class PersonAge
17     {
18         public int Age;
19         public bool HasAge;
20     }

  那要判斷是否有年齡,如Person有一個實例p,則要判斷p對象中的私有屬性age的HasAge是否為true,true表示有年齡,反之沒有。這樣做顯然會引入大量不需要的類,且這些類中有功能重復的、表示一個標示的bool類型的屬性。在C#3中引入可空類型,實現方式為新增了一個NullAble<T>的結構,相信實現應該和我們的PersonAge一樣,只是現在這個系統默認支持的,何不樂乎~

  

 1 public class Person1
 2     {
 3         private string name;
 4         private int? age;
 5         
 6         public Person1(string name, int? age)
 7         {
 8             this.name = name;
 9             this.age = age;
10         }
11     }

  結合C#4中提供的可選參數和默認參數,則可以使用null來初始化age這個值,當需要判斷人是否有年齡,只需判斷p的私有屬性age是否為null即可。

 1 public class Person2
 2     {
 3         private string? name;
 4         private int? age;
 5 
 6         public string? Name { get { return name; } set { name = value; } }
 7         public int? Age { get { return age; } set { age = value; } }
 8 
 9 
10         public Person2(string? name, int? age = null)
11         {
12             this.name = name;
13             this.age = age;
14         }
15     }

  在入口類中去判斷

 1 Person2 p2 = new Person2(null, null);
 2 
 3             //可以使用"?"用null來賦值,來判斷是否有名字和年齡
 4 
 5             if (p2.Age == null)
 6             {
 7                 Console.WriteLine("這個人沒有年齡!!!");
 8             }
 9 
10             if (p2.Name == null)
11             {
12                 Console.WriteLine("這個人沒有名字!!!");
13             }

  總結下,其實只要記住在非引用類型后加一個"?",則可以使用null來賦值。如int? a=null、short? b=null ...

  

  下面來說下LINQ(語言集成查詢),重新寫一個Book類,如下

 1 public class Book
 2     {
 3         public string Author { get; set; }
 4         public int PageSize { get; set; }
 5 
 6         public Book(string author, int pageSize)
 7         {
 8             Author = author;
 9             PageSize = pageSize;
10         }
11 
12         public static List<Book> GetBooks()
13         {
14             return new List<Book> { 
15                 new Book("fish0",800),
16                 new Book("fish1",1800),
17                 new Book("fish2",2800),
18                 new Book("fish3",3800),
19                 new Book("fish4",4800),
20                 new Book("fish5",5800)
21             };
22         }
23     }

  入口頁面使用如下

 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5 
 6             List<Book> list = Book.GetBooks();
 7             //選擇書的頁數大于1000的書并打印
 8 
 9             var matching = from Book b in list
10                            where b.PageSize > 100
11                            select b;
12             foreach (var m in matching)
13             {
14                 Console.WriteLine(m.Author + " " + m.PageSize);
15             }
16 
17             Console.ReadKey();
18         }
19     }

  常常和LINQ一起使用的關鍵字,我覺得是var,因為想讓編譯器判斷是什么類型,這個就是隱式類型,省去一些繁雜的類型輸入。LINQ的語法和SQL幾乎相同,學習的成本會很小,SQL中的join、order by、group by等都可以在C# LINQ中找到對應的法。

  在使用EF等其它ORM框架時,使用LINQ能大大減少代碼量,而且很多的查詢操作都是延時查詢,并不是一次性取出所有的數據,再從中進行篩選,而是通過LINQ生成SQL語句,然后到數據庫中查詢。

  請斧正。

 

posted on 2014-12-25 17:31  a2htray  阅读(502)  评论(0编辑  收藏  举报

导航