SlideShare a Scribd company logo
1 of 60
C#版本3~5的新特性
大綱
• C# 版本3的語言特性
• C#版本4的語言特性
• C#版本5的語言特性
C#版本3新特性
新特性
• var變數
• 新的集合物件初始
化方式
• 屬性簡化語法
• 匿名類別
• 擴展方法
• Lambda陳述式
• Expression
• 部份類別
Var變數
• C#朝不定型別邁進的溫度計
• 本質上仍是強型別,編譯器仍會將其推論導出它真正的型別。
• Var是靜態繫結的變數,亦即它在編譯器編譯時期就已經推導出來了。
Var變數的語法限制
• 只能用在區域變數
• 無法多宣告
• Var本身並非關鍵字,故仍可宣告以var為名的類別,編譯器會優先使用。
• 集合型別需統一
• 使用匿名型別時,指向這個匿名型別的變數必定要是var
• Var變數在使用上,如果不是用於匿名型別則多
半是應用在少打幾個字。
• Var變數若使用過度會造成程式碼可讀性低落,
故,需要注意不要濫用。
.Net的集合
• .Net的集合在.Net Framework 2.0之前沒有泛型功能。
• 集合主要分成三大類:
• 常用集合
• 位元集合
• 特殊化集合
常用集合
• Array
• ArrayList/List
• HashTable/Dictionary
• SortedList/SortedDictionary
• Queue
• Stack
• HashSet
特殊化集合
• NameValueCollection
• StringCollection/StringDictionary
• HybridDictionary
• KeyedCollection<TKey, Titem>
如何選取集合類別(1)-
可捨棄性
• Queue -> 執行Pop方法之後該元素就不存在集合中
• Stack ->執行Pop方法之後該元素就不存在集合中
如何選取集合類別(2)-
循序性
• Queue -> FIFO(First Come First Serve)
• Stack -> LIFO(Last Come First Serve)
• LinkedList<T> -> 單向存取;從頭到尾,或從尾到頭
如何選取集合類別(3)-
隨機性
• ArrayList/StringCollection/List<T> -> 透過以0為啟始的索引存取元素
• HashTable/SortedList/ListDictionary/StringDictionary/Dictionary<TKey,
Tvalue>/SortedDictionary<TKey, Tvalue> -> 透過Key值來存取指定元
素。
• NameObjectCollectionBase/NameValueCollection/KeyedCollection<TKey,
Titem>/SortedList<TKey, Tvalue>-> 可使用Key值或索引值來存取指定
元素。
如何選取集合類別(4)-
順序性
• HashTable -> 依元素的雜湊來排序
• SortedList/SortedDictionary<TKey, Tvalue>/SortedList<TKey, Tvalue> ->
依據開發人員額外實做的IComparer/IComparer<T>類別排序。
• ArrayList/List<T> -> ArrayList會採用開發人員實做的IComparer類別作
為排序演算法;List<T>則是IComparer<T>
集合使用上的重點
• 有幾個在應用上的觀點需要被考慮:
• 資料操作特性
• 資料量
• 資料生命週期
• 執行緒安全
初始化集合
物件的屬性
• 類別即為物件藍圖,容器將依其打造出物件。
• 決定何時打造出物件的是開發人員的Script;決定物件何時死亡是依語
言特性。
• 物件的屬性代表著是物件的特徵,故,其特徵不應該隨意隨時被修改。
• 為解決物件特徵資料的私密性,需以屬性方法開放給外界存取,並在屬
性方法中控管和檢驗輸出/入的值。
C#3.0以前的類別屬性宣告
C# 3.0開始支援的語法
DTO(Data Transfer Object)
• 在兩個Process之間傳遞的資料載體,其目的在於減少兩者的呼叫次數。
• DTO僅有資料無操作行為。
• 減少曝露過多的細節資訊,依需求承載所需的資料。
應用新的屬性宣告特性撰寫DTO
臨時所需的一個物件
• 某些時候會需要一個臨時用來承載資料的物件,但這個物件的生命週
期僅會在一個函數中。
• 雖為匿名型別但是編譯器仍會給予一個自動產生的類別與之對應,其
格式為:
<>_AnonymousType0’2[屬性型別1, 屬性型別2, …]
• 若有多個匿名類別其屬性的個數和資料型別一致,則會考慮重覆使用
自動產生的類別。
匿名類別使用上的限制
• 匿名類別本身並不會實做IDispose介面,故,盡量避免在匿名類別中放置
實做IDispose介面的物件屬性。
• 匿名類別不應放置到泛型集合中。(取出要用特殊方法)
• 匿名類別的物件無法作為參數傳遞。
匿名類別的使用
珍瓏棋局
• 當所開發的系統需與第三方系統和平共存,但第三方系統的程式原始
碼並不在手上,但當前需要添加額外的方法到第三方系統的程式碼中。
天外飛來一筆
• C# 3.0版之後提供擴充方法的功能,開發人員可以藉由這個特性對第三
方或者是.Net原本就提供的類別添加系統所需要的方法。
對DateTime添加方法
擴充方法帶來的遺毒
• 編譯器會到程式所引用的所有命名空間中去搜尋符合條件的擴充方
法。
• 擴充方法本身仍是被編譯成靜態類別中的靜態方法,本身無法提供物
件導向的彈性,故,過多使用擴充方法或讓系統從物件導向程式回到程
序化程式。
• 擴充方法被呼叫時是判定方法名稱,故有可能會發生名稱衝突的狀況。
委派的意義
• SRP(Single Responsibility Principal): 一個類別應該只有一項變因。
• 類別所負擔的責任若過重則該類別在對抗需求變更的能力就會相對
性的對弱。
Lambda語法
• => 這個符號代表的是Goes to,亦即左邊的東西交遞給右邊。
• 左邊: 代表的是函數的輸入參數,可以沒有任何參數,最多也可以有16個。
• 右邊: 代表的是函數陳述式本體,左邊的參數可以在陳述式中使用。
委派與Lambda應用
Lambda類型
• Lambda一共有兩種類型:
• Lambda陳述式: 通常是大括弧框起兩到三行的程式碼。
• Lambda表達式: 沒有大括弧,僅有一行簡單的運算式。
• Lambda陳述式只能轉變成為委派物件;Lambda除了可以轉變成為委派
物件之外還可以轉變成為運算式樹。
Express樹
兩者運算是等價的
Expression樹的應用
• Expression樹以一種結構化的方式將運算式儲存在記憶體中,當運算式
成為樹狀化結構之後就可以依所欲解決的問題領域自行設計出領域
專屬的處理功能。
Express樹的圖示
Expression<Func<int,int>>
n => (n*n)
Body: BinaryExpression
(n*n)
Parameters
[0] = ‘n’
NodeType: ExpressionType
Lambda
ReturnType: Type
System.Int32
屬性
Left: Expression
n
Right: Expression
n
NodeType: ExpressionType
Multiply
屬性
部份類別
• 不論是Windows Form/Web Form兩者在開發模式上都是藉由控制項的
操作來建構出系統,但過去是將所有控制項的屬性設定和事件函數都
混合在一起,這讓程式碼變得臃腫難維護。
事件內容控制項屬性設定
部份類別的特性
• 部份類別的特性是為了將不同觀點的程式邏輯拆分成多個不同的類
別,而這些類別只要加上partial這個關鍵字並且在同一個命名空間中取
同樣的類別名稱,編譯器在編譯的時就會將所有部份類別結合成為一
個類別。
C#版本4新特性
C#版本4新增的特性
• 動態繫結
• 方法的命名/可選參數
• 泛型的協變/逆變
動態繫結
• 動態繫結與靜態繫結不同之處在於何時決定其型別;靜態繫結會在編
譯時期就決定好其資料型別,而動態繫結則是在執行時期才會對其進
行資料型別的查詢。
動態繫結的實例運用
動態繫結的特性與應用時機
• 由於動態繫結的型別判定是在執行時期,故,其執行效率會相對比靜態
繫結的變數還要來得低落。
• 動態繫結由於是在執行時期才能判斷其型別,故,Visual Studio不會在智
慧標籤中顯示動態繫結變數的成員和方法。
• 動態繫結多半應用在異值系統的整合,因為其執行時期決定型別的特
性,因此可以相容許多異質系統的物件。
方法的輸入參數
• 在C#版本4.0之前的函數其輸入參數需要很死版的一個個輸入,縱使此
次呼叫不會使用到某些輸入參數,但是仍需要傳入。
具名參數
• 在呼叫函數時,可以指定要傳入的值是給予那一個輸入參數。
可選參數
• 某些時候函數的輸入參數在大多時候都會是固定某個值,這在C#4.0之
前是必須要Hard Code傳入函數中,但是C# 4.0已經可以直接給予函數
預設值了。
• 當函數宣告某個輸入參數具有預設值,則呼叫端可以忽略不指定傳值
給這個輸入參數,但是亦可傳入所需要的值。
• 可選參數必定是要放置在非可選參數之後,不過可選參數的數量並沒
有限制。
C# 4.0在輸入參數上的進化
泛型的協變/逆變
• 泛型的協變/逆變是用來解決集合物件具有泛型特性時,其內部元素的
型別轉換相容性的另一種規則。
• 物件導向語言本身支援多型的能力,故,C#在泛型集合上針對多型作文
章。
協變
• 協變與一般物件導向在多型方面的規則一致;皆是父類型別的泛型集
合允許放入的元素是子類型別的物件。
• 協變在語法僅是在泛型宣告處加上out這個關鍵字:
• 協變所宣告的泛型型別只能用在方法的輸出上。
逆變
• 逆變的規則與協變正好顛倒過來;逆變的規則是泛型型別是子類型別,
但是允許存取的元素是父類型別的物件。
• 逆變的關鍵字也是相反,採用的是in:
• 要注意一個重點就是逆變宣告的泛型型只能用在方法的輸入參數上。
C#版本5新特性
C#5.0新增的功能特性
• 非同步寫法:async/await
• 方法呼叫者(Caller)
Async/Await
• 非同步呼叫是一種程式撰寫的樣式。
• 非同步呼叫多半應用在需要長時間等候的任務上,其用意在於讓系統
的執行緒(Worker Thread)能夠被釋放去服務新的Request。
非同步執行
Async/Await資源的耗用
• 使用Async/Await會比不使用還要消耗更多的資源;因為其內部實做是
利用一個不斷輪詢處理結果的有限狀態機來達成的。
• Async/Await真正對於系統效能的幫助是在執行緒的釋放,藉此製造出
能夠快速接受大量湧入的Request的效果,但本質上並不是縮短了函數
執行時間。
• Async/Await只能用在方法結尾是Async的函數上,並非所有類別所提供
的方法都能夠使用Async/Await。
C#向弱型別語言更邁進一步
• C#自從3.0版本開始就出現弱型別取向的狀況,相信越往後越會出現原
本只會在JavaScript這類弱型別語言中的語法。
• 在JavaScript中函數可以取得函數呼叫者相關資訊,而在C# 5.0版本亦提
供參數屬性標籤來達成同樣的效果。
Caller Attribute
• CallerMemberName: 取得呼叫者的函數名稱。
• CallerFilePath: 取得呼叫者檔案的完整路徑。
• CallerLineNumber: 取得呼叫者是在那一行呼叫此函數。
Caller標籤的使用方式
總結
縱觀與未來發展
• C#未來將會越來越朝異質平台相容性發展,並且加入更多弱型別語言
的特性。
• C#過去在1.0和2.0時代,採用的商業策略是學習Java語言,故留一下匪夷
所思的坑,未來會逐漸消失與淘汰。
• C# 6.0目前已在蘊釀中,其添加的特性依可信謠言指出: 會有更多讓人
暈倒死的語法蜜糖。

More Related Content

More from 國昭 張

事件風暴-設計衝刺
事件風暴-設計衝刺事件風暴-設計衝刺
事件風暴-設計衝刺國昭 張
 
事件風暴-領域建模
事件風暴-領域建模事件風暴-領域建模
事件風暴-領域建模國昭 張
 
Scrum essential
Scrum essentialScrum essential
Scrum essential國昭 張
 
DDD架構設計
DDD架構設計DDD架構設計
DDD架構設計國昭 張
 
DDD系統分析
DDD系統分析DDD系統分析
DDD系統分析國昭 張
 
Asp.net core v1.0
Asp.net core v1.0Asp.net core v1.0
Asp.net core v1.0國昭 張
 
Redux+react js
Redux+react jsRedux+react js
Redux+react js國昭 張
 
架構設計-資料存取的選擇
架構設計-資料存取的選擇架構設計-資料存取的選擇
架構設計-資料存取的選擇國昭 張
 
前端自動化工具
前端自動化工具前端自動化工具
前端自動化工具國昭 張
 
例外處理與單元測試
例外處理與單元測試例外處理與單元測試
例外處理與單元測試國昭 張
 
ASP.Net WebAPI經驗分享
ASP.Net WebAPI經驗分享ASP.Net WebAPI經驗分享
ASP.Net WebAPI經驗分享國昭 張
 
ASP.Net MVC Framework
ASP.Net MVC FrameworkASP.Net MVC Framework
ASP.Net MVC Framework國昭 張
 
Team Foundation Server
Team Foundation ServerTeam Foundation Server
Team Foundation Server國昭 張
 
SQL Server效能調校
SQL Server效能調校SQL Server效能調校
SQL Server效能調校國昭 張
 

More from 國昭 張 (20)

事件風暴-設計衝刺
事件風暴-設計衝刺事件風暴-設計衝刺
事件風暴-設計衝刺
 
事件風暴-領域建模
事件風暴-領域建模事件風暴-領域建模
事件風暴-領域建模
 
單元測試
單元測試單元測試
單元測試
 
Docker實務
Docker實務Docker實務
Docker實務
 
Scrum essential
Scrum essentialScrum essential
Scrum essential
 
Docker基礎
Docker基礎Docker基礎
Docker基礎
 
DDD架構設計
DDD架構設計DDD架構設計
DDD架構設計
 
DDD系統分析
DDD系統分析DDD系統分析
DDD系統分析
 
DDD引導
DDD引導DDD引導
DDD引導
 
前端測試
前端測試前端測試
前端測試
 
Asp.net core v1.0
Asp.net core v1.0Asp.net core v1.0
Asp.net core v1.0
 
Redux+react js
Redux+react jsRedux+react js
Redux+react js
 
React js
React jsReact js
React js
 
架構設計-資料存取的選擇
架構設計-資料存取的選擇架構設計-資料存取的選擇
架構設計-資料存取的選擇
 
前端自動化工具
前端自動化工具前端自動化工具
前端自動化工具
 
例外處理與單元測試
例外處理與單元測試例外處理與單元測試
例外處理與單元測試
 
ASP.Net WebAPI經驗分享
ASP.Net WebAPI經驗分享ASP.Net WebAPI經驗分享
ASP.Net WebAPI經驗分享
 
ASP.Net MVC Framework
ASP.Net MVC FrameworkASP.Net MVC Framework
ASP.Net MVC Framework
 
Team Foundation Server
Team Foundation ServerTeam Foundation Server
Team Foundation Server
 
SQL Server效能調校
SQL Server效能調校SQL Server效能調校
SQL Server效能調校
 

C#版本3~5的新特性