內 容 簡 介
這是一本注重實際開發、接地氣的.NET技術書籍。作者結合多年的開發經驗,用通俗易懂的語言,深入淺出地講解在.NET實際開發工作中的實用知識點。全書分為基礎篇和設計篇兩大部分。在基礎篇,解釋了“原子操作”、“阻塞方法與非阻塞方法”、“框架與庫”、“調用與回調”等術語,重點闡述.NET開發的三大基礎知識點:數據類型、對象的生命期以及委托與事件。在設計篇,主要講解“泵”結構在一些主流框架中的應用,以及它在Socket網絡編程、Web服務器開發等實際項目中起到的關鍵作用;并從軟件設計模式、軟件設計原則以及代碼依賴3個方面,對軟件架構進行了深入淺出的闡釋。
本書適合已經入門且有一定編程經驗并準備向高手邁進的.NET開發者。本書同時也可作為大中專院校和.NET技術培訓機構的參考教材。
前 言
“勤于總結”一直都是學習的最好方式之一,學習編程也一樣,總結的過程會促使你持續不斷地思考,從一個知識點向另一個知識點擴散,對于之前已經了解的知識,你會理解得更加深刻,而對于那些在總結過程中又觸發到的新知識,也是一種額外的收獲。筆者對此深有體會,一個不會總結的技術開發者是難以成為一名優秀的程序員的。筆者習慣將工作中的技術心得記錄在自己的博客中,本書便是筆者從事.NET開發多年來記錄在博客中的一些技術總結,經過重新整理、發掘和完善,便形成了本書。希望這些技術總結能夠給.NET開發者帶來一些幫助。
1.本書特色
.NET技術有著廣泛的應用范疇,從Windows 桌面應用,到ASP.NET Web應用,到WCF分布式應用,到Windows Mobile嵌入式應用,到Windows Phone移動應用,到ADO.NET數據庫應用,到XML Web Service,.NET無處不在。因此,現在市面上關于.NET開發的書籍可謂之多,但筆者在本書中沒有介紹一些平時幾乎用不到的高深莫測的技術,如代碼安全性或者IL語言這些底層的內容,也避免介紹一些簡單的基礎內容,例如類型的聲明、語法、開發環境或者關鍵字的介紹等。本書總結了筆者認為在實際 .NET開發工作中比較實用的知識點,如解釋了諸如“原子操作”、“阻塞方法與非阻塞方法”、“框架與庫”、“調用與回調”等這些常見但沒有標準定義的編程術語;重點闡述了.NET開發的三大基礎知識點:數據類型、對象的生命期以及委托與事件;詳細介紹了“泵”結構在一些主流框架諸如Windows桌面GUI框架中的應用,以及它在Socket網絡編程、Web服務器開發等實際項目開發中起到的關鍵作用;此外在軟件架構方面,本書分別從軟件設計模式、軟件設計原則以及代碼依賴3個方面也一一進行了說明。總之,這是一本注重實際開發、接地氣的 .NET技術書籍。
2.讀者對象
本書適合已經入門,有一定編程經驗并準備向高手邁進的 .NET開發者,包括以下人員:
.NET工程師
在校計算機相關專業 .NET方向大學生
從其他面向對象語言轉向學習 .NET編程的開發者
3.主要內容
全書共分12章。第1~7章為基礎篇,分別涉及 .NET平臺介紹、編程術語解釋、數據類型、對象生命期、委托與事件、異步編程以及 .NET中的組件;第8~12章為設計篇,主要介紹代碼中的“泵”結構、軟件設計模式、軟件設計原則以及代碼依賴。其中第8章和第9章主要是為了引入代碼中“泵”的概念,為第10章講“泵”結構做鋪墊。各章的主要內容簡述如下。
第1章主要講述 .NET平臺的組成,強調 .NET平臺出現的意義是改善了傳統Windows的開發模式,而非專門提供一個跨平臺的開發支持。
第2章是筆者從這幾年的工作經歷中總結出來的有關 .NET編程的一些經驗,對 .NET實際開發工作有所幫助。
第3章介紹 .NET編程的基礎,即數據類型。筆者分別從值類型與引用類型的內存分配、賦值與復制以及對象判等方面進行了說明。
第4章講述 .NET對象的“從生到死”,以及怎樣管理好對象的非托管資源,最后提出正確實現Dispose模式的方法,并說明為什么Dispose一個對象并不代表該對象死亡。
第5章講述委托的結構以及它在 .NET編程中的重要地位。程序的執行過程就是方法的調用過程,委托作為調用方法的一種手段,貫穿著整個 .NET編程領域,之后說明 .NET中事件與委托的關系,并且提到了事件編程的標準規范。
第6章講述“異步編程模型”,闡述異步編程的必要性,介紹怎樣使用委托去異步調用一個方法,以及異步編程過程中需要注意的一些事項,比如跨線程訪問、線程安全等。
第7章介紹 .NET編程中組件的定義,以及組件存在的意義。還介紹了“容器-組件-服務模型”,并提到一般集成開發環境(如Visual Studio)中窗體設計器的原理,之后介紹組件的兩種狀態:運行時和設計時,以及區分組件當前狀態的方法。
第8章主要重溫了經典桌面GUI框架,并介紹 “Windows消息”、“消息泵”以及“窗口過程”等概念,本章引入了代碼中的“泵”的概念。
第9章介紹兩種Socket網絡通信模式,即TCP通信與UDP通信,并強調了“泵”結構在網絡通信中的應用。
第10章介紹“泵”結構的幾個常見應用場景,如Socket通信、桌面GUI框架以及Web服務器的實現等。
第11章介紹軟件開發中的設計模式與設計原則。
第12章講述代碼依賴不可完全避免的原因、負面影響以及如何降低代碼依賴程度。
4.關于注釋與配圖
本書配備了大量的圖解和代碼。為了讓讀者更好地理解示例代碼和配圖,筆者在每段代碼和配圖下面都加上了詳細的中文說明文字。因此書中所示代碼均為“說明性”代碼,并不確保能在編譯器中編譯通過,代碼語言為C#,默認 .NET版本為 .NET Framework 3.5,但筆者認為本書所講到的內容受 .NET版本及其語言限制對代碼影響不大。另外書中以“注”字開頭的提示性文字更值得閱讀,很多都是筆者認為值得注意的地方。
本書源代碼下載地址為http://www.cnblogs.com/cbook/p/3908393.html
5.勘誤與支持
本書由周見智、博圖軒編著,參與本書編寫的還有鄧世健、趙曉芳、萬建邦、劉耀宗。讀者QQ群為440170769,這里將隨時發布與本書有關的信息。
由于筆者水平有限,書中難免會出現一些錯漏,對此懇請各位讀者多提寶貴意見,以便本書再版時能予以修正,意見可發送至郵箱zhouzhi@syxysoft.com與筆者探討。同時可以訪問作者博客:http://www.cnblogs.com/xiaozhi_5638,微博:http://weibo.com/netproduct。
編 者
目 錄
第1章 另辟蹊徑:解讀.NET 1
1.1 前.NET時代 2
1.2 .NET的組成 3
1.2.1 .NET中的語言 4
1.2.2 .NET中的框架庫 5
1.2.3 公共類型系統 5
1.2.4 公共語言規范 5
1.2.5 公共語言運行時 6
1.2.6 .NET程序的運行流程 7
1.3 .NET中的程序集 8
1.3.1 程序集與EXE文件的區別 8
1.3.2 程序集的組成 9
1.3.3 程序集的特點 10
1.4 .NET的跨平臺 10
1.4.1 Write Once, Run Anywhere的真實現狀 10
1.4.2 .NET與Java平臺出現的目的 11
1.4.3 重新看待.NET 12
1.5 .NET平臺出現的意義 12
1.6 本章回顧 14
1.7 本章思考 14
第2章 高屋建瓴:梳理編程約定 15
2.1 代碼中的Client與Server 16
2.2 方法與線程的關系 17
2.3 調用線程與當前線程 19
2.4 阻塞方法與非阻塞方法 20
2.5 UI線程與線程 21
2.6 原子操作 22
2.7 線程安全 22
2.8 調用與回調 26
2.9 托管資源與非托管資源 27
2.10 框架與庫 28
2.11 面向(或基于)對象與面向(或基于)組件 29
2.12 接口 30
2.13 協議 32
2.14 本章回顧 36
2.15 本章思考 36
第3章 編程之基礎:數據類型 37
3.1 引用類型與值類型 38
3.1.1 內存分配 39
3.1.2 字節序 41
3.1.3 裝箱與拆箱 42
3.2 對象相等判斷 43
3.2.1 引用類型判等 43
3.2.2 簡單值類型判等 44
3.2.3 復合值類型判等 45
3.3 賦值與復制 48
3.3.1 引用類型賦值 48
3.3.2 值類型賦值 49
3.3.3 傳參 50
3.3.4 淺復制 53
3.3.5 深復制 55
3.4 對象的不可改變性 59
3.4.1 不可改變性定義 59
3.4.2 定義不可改變類型 60
3.5 本章回顧 62
3.6 本章思考 62
第4章 物以類聚:對象也有生命 65
4.1 堆和棧 66
4.2 堆中對象的出生與死亡 69
4.2.1 引用和實例 69
4.2.2 析構方法 71
4.2.3 正確使用對象 73
4.3 管理非托管資源 75
4.3.1 釋放非托管資源的最佳時間 75
4.3.2 繼承與組合中的非托管資源 77
4.4 正確使用IDisposable接口 82
4.4.1 Dispose模式 83
4.4.2 對象的Dispose()和Close() 87
4.5 本章回顧 88
4.6 本章思考 88
第5章 重中之重:委托與事件 91
5.1 什么是.NET中的委托 92
5.1.1 委托的結構 92
5.1.2 委托鏈表 95
5.1.3 委托的“不可改變”特性 101
5.1.4 委托的作用 103
5.2 事件與委托的關系 105
5.3 使用事件編程 107
5.3.1 注銷跟注冊事件同樣重要 107
5.3.2 多線程中使用事件 107
5.3.3 委托鏈表的分步調用 109
5.3.4 正確定義一個使用了事件的類 111
5.4 弱委托 116
5.4.1 強引用與弱引用 116
5.4.2 弱委托的定義 119
5.4.3 弱委托的使用場合 121
5.5 本章回顧 121
5.6 本章思考 122
第6章 線程的升級:異步編程模型 123
6.1 異步編程的必要性 124
6.1.1 同步調用與異步調用 124
6.1.2 異步調用的優點 125
6.2 委托的異步調用 126
6.2.1 BeginInvoke與EndInvoke 126
6.2.2 AsyncCallback 128
6.2.3 處理異步調用時的異常 131
6.2.4 異步調用的應用 132
6.3 非委托的異步調用 134
6.3.1 異步方法 134
6.3.2 FileStream.BeginRead/FileStream.BeginWrite 136
6.4 異步編程時的注意事項 137
6.5 本章回顧 138
6.6 本章思考 138
第7章 可復用代碼:組件的來龍去脈 141
7.1 .NET中的組件 142
7.1.1 組件的定義 142
7.1.2 Windows Forms中的組件 142
7.1.3 Windows Forms中的控件 143
7.2 容器-組件-服務模型 144
7.2.1 容器的另類定義 144
7.2.2 容器與組件的合作 145
7.2.3 窗體設計器 150
7.3 設計時與運行時 154
7.3.1 組件的設計時與運行時 154
7.3.2 區分組件的當前狀態 155
7.3.3 組件狀態的應用 157
7.4 控件 157
7.4.1 控件基類 157
7.4.2 用戶自定義控件 158
7.5 本章回顧 160
7.6 本章思考 160
第8章 經典重視:桌面GUI框架揭秘 163
8.1 了解傳統Win32應用程序的必要性 164
8.2 Win32應用程序的結構 165
8.2.1 運行平臺決定程序結構 165
8.2.2 Windows消息循環 167
8.2.3 窗口過程 169
8.2.4 創建基于Win32的單窗體應用程序 171
8.2.5 創建基于Win32的多窗體應用程序 178
8.3 .NET Winform程序與傳統Win32程序的關聯 184
8.4 Windows Forms框架 184
8.5 Winform程序的結構 187
8.5.1 UI線程 188
8.5.2 消息循環 189
8.5.3 創建窗體 195
8.5.4 窗口過程 197
8.6 模式窗體與非模式窗體 200
8.7 本章回顧 205
8.8 本章思考 205
第9章 溝通無礙:網絡編程 207
9.1 兩種Socket通信方式 208
9.1.1 IP與端口 208
9.1.2 基于連接的TCP通信 209
9.1.3 基于無連接的UDP通信 211
9.1.4 應用層協議 212
9.1.5 .NET中Socket編程的
相關類型 215
9.2 TCP通信的實現 217
9.2.1 定義TCP通信應用層協議 218
9.2.2 編寫TCP通信服務端 219
9.2.3 編寫TCP通信客戶端 225
9.3 UDP通信的實現 227
9.3.1 定義UDP通信應用層協議 228
9.3.2 編寫UDP通信客戶端 229
9.4 異步編程在網絡編程中的應用 235
9.4.1 異步發送數據 237
9.4.2 異步實現“泵”結構 238
9.5 本章回顧 241
9.6 本章思考 241
第10章 動力之源:
代碼中的“泵” 243
10.1 “泵”的概念 244
10.1.1 現實生活中的“泵” 244
10.1.2 代碼中的“泵” 245
10.1.3 代碼中“泵”的作用 247
10.2 常見的“泵”結構 249
10.2.1 桌面GUI框架中的“泵” 249
10.2.2 Socket通信中的“泵” 250
10.2.3 Web服務器中的“泵” 251
10.3 “泵”對框架的意義 258
10.3.1 重新回到框架定義 258
10.3.2 框架離不開“泵” 258
10.4 本章回顧 259
10.5 本章思考 259
第11章 規繩矩墨:模式與原則 261
11.1 軟件的設計模式 262
11.1.1 觀察者模式 262
11.1.2 Windows Forms中的觀察者模式 265
11.1.3 設計模式分類 267
11.2 軟件的設計原則 267
11.2.1 SOLID原則概述 267
11.2.2 單一職責原則 268
11.2.3 開閉原則 270
11.2.4 里氏替換原則 272
11.2.5 接口隔離原則 275
11.2.6 依賴倒置原則 276
11.3 設計模式與設計原則對框架的意義 278
11.4 本章回顧 279
11.5 本章思考 279
第12章 難免的尷尬:代碼依賴 281
12.1 從面向對象開始 282
12.1.1 對象基礎:封裝 282
12.1.2 對象擴展:繼承 286
12.1.3 對象行為:多態 289
12.2 不可避免的代碼依賴 292
12.2.1 依賴存在的原因 292
12.2.2 耦合與內聚 294
12.2.3 依賴造成的“尷尬” 295
12.3 降低代碼依賴 297
12.3.1 認識“抽象”與“具體” 297
12.3.2 再看“依賴倒置原則” 299
12.3.3 依賴注入 302
12.4 框架的“代碼依賴” 305
12.4.1 控制轉換 305
12.4.2 依賴注入對框架的意義 306
12.5 本章回顧 306
12.6 本章思考 306