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語句,然后到數據庫中查詢。

  請斧正。

时间: 2024-11-06 11:56:43

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

默認打開pr_debug和dev_dbg

在進行Linux驅動開發時經常見到使用pr_debug和dev_dbg打印驅動的log,如果在內核配置時選擇了CONFIG_DYNAMIC_DEBUG宏,那麼就可以利用類似下面的命令打開對應文件的log: echo -n "file xxx.c +p" > /sys/kernel/debug/dynamic_debug/control 但是有時候我們需要看到這個文件在內核啓動階段的log,那麼改怎麼辦呢? 這裏有兩種方法: 方法一 修改內核傳參 修改bootloader傳遞給ke

日志秘密 Windows登錄類型知多少

如果你留意Windows系統的安全日志,在那些事件描述中你將會發現裡面的"登錄類型"並非全部相同,難道除了在鍵盤上進行交互式登錄(登錄類型1)之外還有其它類型嗎? 不錯,Windows為了讓你從日志中獲得更多有價值的信息,它細分了很多種登錄類型,以便讓你區分登錄者到底是從本地登錄,還是從網絡登錄,以及其它更多的登錄方式.因為了解了這些登錄方式,將有助於你從事件日志中發現可疑的黑客行為,並能夠判斷其攻擊方式.下面我們就來詳細地看看Windows的登錄類型. 登錄類型2:交互式登錄(Int

GO語言基礎教程:數據類型,變量,常量

GO類似PHP,每行的結尾要加分號來結束,不同點在於GO對此並不強制,這一點又像javascript,另外GO的語句塊是用一對大括號來包裹的,但是go要求左大括號必須要在語句的結尾處,不能在行首出現左大括號,這是一個新的特性,至少在我接觸的編程語言中第一次遇到這種狀況.還有就是GO對大小寫敏感,這一點相信大家不會有什麽爭議.    GO語言的註釋方法和PHP是相同的,單行註釋用//,而多行註釋用/*註釋內容*/,這一點是沒差別的. Go有眾所周知的數據類型int,這個類型很特殊,他會自動根據您的

PHP中的常量默認是全局變量

define("LEO","歡迎來到PHP世界!"); function show(){ echo LEO; } show(); PHP中的常量默認是全局變量,可以在任何地方調用 define(name,value,true) 這個函數接收3個參數.最好一個參數表示是否區分大小寫(true不區分,false區分)

作業系統的類型

依處理方式而分 整批處理作業系統(Batch processing OS) 處理方式:將欲處理的資料或程式整批集中,置於如卡片.紙帶.磁帶.磁碟等儲存在媒體內,當要處理時,CPU才會到媒體中讀取資料後加以處理. 優點:整批處理作業系統是第一代作業系統,比起沒有作業系統時,更有效地改進了電腦的作業效率,減少大部份人工操作的比率. 缺點:因為CPU速度遠較存取資料的I/O為快,所以此方式CPU常被閒置,效率低. 分時作業系統(Time-sharing OS) 處理方式:CPU每次分配給各程序式(pr

實現樹樁類型結構及其相應的操作【增刪查改和移動】

<h1>一.創建樹樁結構對應的表</h1><p>1.創建樹樁層次結構表</p><p>樹狀結構表採用鏈結構的設計方式,每個節點包含一個當前節點指針ID.下一節點指針ID,以及當前節點的相關信息:節點名稱.順序.有效性.是否為葉子.層次,以下為創建表結構的SQL語句</p><pre class="code" name="pre-TypeConfig">    CREATE TABLE [

Oracle Long 類型欄位處理

Long 數據類型的特點 1.LONG 数据类型中存储的是可变长字符串,最大长度限制是2GB. 2.对于超出一定长度的文本,基本只能用LONG类型来存储,数据字典中很多对象的定义就是用LONG来存储的.1.LONG 数据类型中存储的是可变长字符串,最大长度限制是2GB. 2.对于超出一定长度的文本,基本只能用LONG类型来存储,数据字典中很多对象的定义就是用LONG来存储的. 3.LONG类型主要用于不需要作字符串搜索的长串数据,如果要进行字符搜索就要用varchar2类型. 4.很多工具,包括

從Android端鎖定慣用網路類型

Android的慣用網路類型, 也就是preferred network mode, 是儲存在SettingsProvider中. 當然, modem中也會儲存一份, 但依照Android的設計, 是以SettingsProvider中所存放的使用者設定值為主, 若AP core和modem不同步時, 就會由AP core主動向modem端發起同步的請求. 從Android M開始, Android Settingsprovider的儲存方式改由原本的databases換成XML檔,因此,我們只

C#引用C++ Dll 所有類型轉換的方式(转)

//C++中的DLL函數原型為 //extern "C" __declspec(dllexport) bool 方法名一(const char* 變量名1, unsigned char* 變量名2) //extern "C" __declspec(dllexport) bool 方法名二(const unsigned char* 變量名1, char* 變量名2) //C#調用C++的DLL搜集整理的所有數據類型轉換方式,可能會有重復或者多種方案,自己多測試 //c