首页 > 代码库 > 02.C#可空類型、默認參數、LINQ(一章1.3-1.4)

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 PersonAge17     {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 list10                            where b.PageSize > 10011                            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語句,然后到數據庫中查詢。

  請斧正。

 

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