一. 公共語言運行庫(CLR)
——————————————————————————————————————————————————————
1.3.4 通過異常處理錯誤
.NET Framework 可以根據異常使用相同的機制處理錯誤情況
.NET提供了一種基礎結構,讓面向 .NET的編譯器支持異常處理。特別是它提供了一組 .NET類來表示異常,
——————————————————————————————————————————————————————
1.3.5 特性的使用
特性(attribute)是使用C++編寫COM組件的開發人員很熟悉的一個功能(在Microsoft的COM接口定義語言(Interface
Definition Language,IDL)中使用特性)。特性最初是爲了在程序中提供與某些項相關的額外信息,以供編譯器使用。
.NET支持特性,因此現在C++、C#和Visual
Basic 2008也支持特性。但在.NET中,對特性的革新是建立了一個機制,通過該機制可以在源代碼中定義自己的特性。這些用戶定義的特性將和對應數據類型或方法的元數據放在一起,這對於文檔說明書十分有用,它們和反射技術一起使用,以根據特性執行編程任務。另外,與.NET的語言無關性的基本原理一樣,特性也可以在一種語言的源代碼中定義,而被用另一種語言編寫的代碼讀取。
——————————————————————————————————————————————————————
程序集 (assembly)是包含編譯好的、面向.NET
Framework的代碼的邏輯單元。
程序集的一個重要特性 是它們包含的元數據描述了對應代碼中定義的類型和方法。程序集也包含描述程序集本身的元數據,這種程序集元數據包含在一個稱爲"程序集清單"的區域中,可以檢查程序集的版本及其完整性。
ildasm是一個基於Windows的實用程序,可以用於檢查程序集的內容,包括程序集清單和元數據。第17章將介紹ildasm。
有了程序集後,因爲所有的元數據都與程序的可執行指令存儲在一起。注意,即使程序集存儲在幾個文件中,數據也不會出現不同步的問題。這是因爲包含程序集入口的文件也存儲了其他文件的細節、散列和內容,如果一個文件被替換,或者被塞滿,系統肯定會檢測出來,並拒絕加載程序集。
程序集有兩種類型:共享程序集和私有程序集。
——————————————————————————————————————————————————————
私有程序集是最簡單的一種程序集類型。私有程序集一般附帶在某個軟件上,且只能用於該軟件。附帶私有程序集的常見情況是,以可執行文件或許多庫的方式提供應用程序,這些庫包含的代碼只能用於該應用程序。
因爲私有程序集完全是自含式 的,所以安裝它的過程就很簡單。只需把相應的文件放在文件系統的對應文件夾中即可(不需要註冊表項),這個過程稱爲"0影響(xcopy)安裝"。
——————————————————————————————————————————————————————
共享程序集是其他應用程序可以使用的公共庫。因爲其他軟件可以訪問共享程序集,所以需要採取一定的保護措施來防止以下風險:
· 名稱衝突 ,另一個公司的共享程序集執行的類型與自己的共享程序集中的類型同名。因爲客戶機代碼理論上可以同時訪問這些程序集,所以這是一個嚴重的問題。爲了避免名稱衝突,共享程序集應根據私鑰加密法指定一個名稱 ( 私有程序集只需要指定與其主文件名相同的名稱即可 ) 。該名稱稱爲強名 (strong
name),並保證其唯一性,它必須由要引用共享程序集的應用程序來引用。
· 程序集被同一個程序集的不同版本覆蓋 -- 新版本與某些已有的客戶機代碼不兼容。
這些問題的解決方法是把共享程序集放在文件系統的一個特定的子目錄樹中,稱爲全局程序集高速緩存 (GAC)。
與覆蓋程序集相關的問題,可以通過在程序集清單中指定版本信息來解決,也可以通過同時安裝來解決。
——————————————————————————————————————————————————————
因爲程序集存儲了元數據,包括在程序集中定義的所有類型和這些類型的成員的細節,所以可以 編程訪問這些 元數據。這個技術稱爲反射,第13章詳細介紹了它們。該技術很有趣,因爲它表示託管代碼實際上可以檢查其他託管代碼,甚至檢查它自己,以確定該代碼的信息。它們常常用於獲取特性的詳細信息,也可以把反射用於其他目的,例如作爲實例化類或調用方法的一種間接方式,如果把方法上的 類名指定爲字符串,就可以選擇類來實例化方法,以便在 運行時調用,而不是在編譯時調用,例如根據用戶的輸入來調用(動態綁定)。
——————————————————————————————————————————————————————
.NET基類是一個內容 豐富的託管代碼類集合 ,它可以完成以前要通過Windows
API來完成的絕大多數任務。這些類派生自與中間語言相同的對象模型,也基於單一繼承性。無論.NET基類是否合適,都可以實例化對象,也可以從它們派生自己的類。
WinCV是一個基於Windows的實用程序,可以用於瀏覽基類庫中的類、結構、接口和枚舉。本書將在第15章介紹WinCV。
——————————————————————————————————————————————————————
命名空間是 .NET避免類名衝突 的一種方式。
如果沒有顯式提供命名空間,類型就添加到一個沒有名稱的全局命名空間中。
Microsoft建議 在大多數情況下,都至少要提供 兩個嵌套的命名空間名,第一個是公司名,第二個是技術名稱或軟件包的名稱,而類是其中的一個成員,例如 YourCompanyName.Sales
Services.Customer。在大多數情況下,這麼做可以保證類的名稱不會與其他組織編寫的類名衝突。
——————————————————————————————————————————————————————
1.7 用C#創建 .NET應用程序
C#可以用於創建控制檯應用程序
——————————————————————————————————————————————————————
ASP是用於創建帶有動態內容 的Web 頁面的一種 Microsoft技術。
ASP也有缺點。服務器端代碼是 解釋性的,ASP文件很難維護 ,不是結構化的, ASP有時開發起來困難,因爲它 不支持錯誤處理和類型檢查。
1. ASP.NET的特性
ASP.NET頁面是結構化。每個頁面繼承System.Web.UI. Page類,可以重寫在 Page對象的生存期中調用的一系列方法。因爲可以把一個頁面的功能放在有明確含義的事件處理程序中,所以 ASP.NET比較容易理解。
最清楚的是,ASP.NET的後臺編碼功能允許 進一步採用 結構化的方式。 ASP.NET允許把頁面的服務器端功能 單獨放在一個類中,把該類 編譯爲DLL,並把該 DLL放在H-TML 部分下面的一個目錄中。放在頁面頂部的後臺編碼指令將把該文件與其 DLL關聯起來。當瀏覽器請求該頁面時, Web服務器就會在頁面的後臺 DLL中引發類中的事件。
最後,ASP.NET 在性能的提高上非常明顯。傳統的 ASP頁面是和每個頁面請求一起解釋,而 Web服務器是在編譯後高速緩存 ASP.NET頁面。這表示以後對ASP.NET頁面的請求就比 ASP頁面第一次執行的速度快得多。
ASP.NET還易於編寫通過瀏覽器顯示窗體的頁面,這在內聯網環境中會使用。傳統的方式是基於窗體的應用程序提供一個功能豐富的用戶界面,但較難維護,因爲它們運行在非常多的不同機器上。因此,當用戶界面是必不可少的,並可以爲用戶提供擴展支持時,人們就會依賴基於窗體的應用程序。
2. Web窗體
爲了簡化Web 頁面的結構, Visual
Studio 2008提供了Web 窗體。它們允許以創建 Visual
Basic 6或C++ Builder窗口的方式圖形化地建立 ASP.NET頁面;換言之,就是把控件從 工具箱拖放到窗體上,再考慮窗體的代碼,爲控件編寫事件處理程序。在使用 C#創建Web窗體時,就是創建一個 繼承自Page基類 的C# 類,以及把這個類看作是後臺編碼的 ASP.NET頁面。當然不必使用C#創建 Web窗體,而可以使用Visual
Basic 2008或另一種 .NET語言來創建。
3. Web服務器控件
用於添加到Web窗體上的控件與 ActiveX控件並不是同一種控件,它們是 ASP.NET命名空間中的XML標記 ,當請求一個頁面時,Web瀏覽器會動態地把它們轉換爲 HTML和客戶端腳本。Web服務器能以 不同的方式顯示相同的服務器端控件,產生一個對應於請求者特定 Web瀏覽器的轉換 。這意味着現在很容易爲 Web頁面編寫相當複雜的用戶界面,而不必擔心如何確保頁面運行在可用的任何瀏覽器上,因爲 Web窗體會完成這些任務。
可以使用C#或VisualBasic2008擴展Web窗體工具箱。創建一個新服務器端控件,僅是執行.NET的System.Web.UI.WebControls.WebControl 類而已。
4. XML Web服務
目前,HTML 頁面解決了 World
Wide Web上的大部分通信問題 。有了XML ,計算機就可以用一種 獨立於設備的格式,在 Web上彼此通信。將來,計算機可以使用 Web和XML 交流信息,而不是專用的線路和專用的格式,例如 EDI
(Electronic Data Interchange) 。XML
Web服務是爲面向 Web的服務而設計的,即遠程計算機彼此提供可以分析和重新格式化的動態信息,最後顯示給用戶。 XML
Web服務是計算機給Web上的其他計算機以 XML格式顯示信息的一種便利方式。
在技術上,.NET上的 XML
Web服務是給請求的客戶返回 XML而不是HTML 的ASP.NET頁面。這種頁面有後臺編碼的 DLL,它包含了派生自WebService類的類。 Visual
Studio 2008 IDE提供的引擎簡化了 Web服務的開發。
公司選擇使用XML
Web服務主要有兩個原因。第一是因爲它們 依賴於HTTP,而 XML
Web服務可以把現有的網絡 (HTTP)用作傳輸信息的媒介。第二是因爲 XML
Web服務使用XML ,該數據格式是自我描述的、非專用的、獨立於平臺的。
——————————————————————————————————————————————————————
1.7.3 使用Windows
Presentation Foundation(WPF)
有一種最新的技術叫做 Windows Presentation
Foundation(WPF) 。WPF在建立應用程序時使用 XAML。XAML 表示可擴展的應用程序標記語言 (Extensible
Application Markup Language) 。
XAML是用於創建窗XML聲明,它代表 WPF應用程序的所有可視化部分和操作。雖然可以編程利用 WPF應用程序,但WPF是邁向 聲明性編程的一步,而聲明性編程是編程業的 趨勢。聲明性編程是指,不是利用編譯語言,如 C#、VB 或Java,通過編程來創建對象,而是通過 XML類型的編程來聲明所有的元素。
——————————————————————————————————————————————————————
1.7.6 Windows Communication Foundation(WCF)
通過基於Microsoft 的技術,可以採用許多方式將 數據和服務從一處 移動到另一處。例如,可以使用 ASP.NET
Web服務、.NET Remoting 、Enterprise
Services和用於初學者的 MSMQ。應採用哪種技術?這要考慮具體要達到的目標,因爲每種技術都適合於不同的場合。
因此, Microsoft把所有這些技術集成在一起,放在 .NET
Framework 3.0和3.5 中。現在只有一種移動數據的方式 --
Windows Communication Foundation(WCF) 。WCF允許建立好服務後,只要修改配置文件,就可以用多種方式提供該服務 (甚至在不同的協議下)。 WCF是一種連接各種系統的強大的新方式。
——————————————————————————————————————————————————————
2.8.2 命名空間的別名
using alias = NamespaceName;
alias::NamespaceExample NSE = new alias::NamespaceExample();
注意命名空間別名的 修飾符是::
——————————————————————————————————————————————————————
——————————————————————————————————————————————————————
3.8 擴展方法
有許多方法擴展類。如果有類的源代碼,繼承(如第 4章所述)就是給對象添加功能的好方法。但如果沒有源代碼,該怎麼辦?此時可以使用擴展方法,它允許改變一個類,但不需要類的源代碼。
——————————————————————————————————————————————————————
——————————————————————————————————————————————————————
7.1 委託
當要把方法 傳送給其他方法 時,需要使用委託。
· 事件-- 一般是通知代碼發生了什麼事件。GUI編程主要是處理事件。在發生事件時,運行庫需要知道應執行哪個方法。這就需要把 處理事件 的方法傳送爲委託 的一個參數 。這些將在本章後面討論。
在C和 C++中,只能提取函數的地址,並傳送爲一個參數。 C是沒有類型安全性的。可以把任何函數傳送給需要函數指針的方法。這種直接的方法會導致一些問題,例如類型的安全性,在進行面向對象編程時,方法很少是孤立存在的,在調用前,通常需要與類實例相關聯。而這種方法並沒有考慮到這個問題。所以 .NET
Framework在語法上不允許使用這種直接的方法。如果要傳遞方法,就必須把方法的細節封裝在一種新類型的對象中,即委託。委託只是一種特殊的對象類型,其特殊之處在於,我們以前定義的所有對象都包含數據,而 委託包含的只是 方法的地址。
——————————————————————————————————————————————————————
理解委託的一個要點是它們的類型 安全性非常高。在定義委託時,必須給出它所代表的方法 簽名和返回類型 等全部細節。
理解委託的一種好方式是把委託當作給方法簽名和返回類型指定名稱。
委託實現爲派生自基類 System. Multicast
Delegate的類,System.MulticastDelegate 又派生自基類 System.Delegate。
給定委託的實例可以表示任何類型的 任何對象上的 實例方法或 靜態方法-- 只要方法的簽名匹配於委託的簽名即可。
——————————————————————————————————————————————————————
7.1.6 匿名方法
到目前爲止,要想使委託工作,方法必須已經存在(即委託是用方法的簽名定義的)。但使用委託還有另外一種方式:即通過匿名方法。匿名方法是用作委託參數的一個代碼塊。
用匿名方法定義委託的語法與前面的定義並沒有區別。但在實例化委託時,就有區別了。
——————————————————————————————————————————————————————
事件接收器是指在發生某些事情時被通知的任何應用程序、對象或組件。當然,有事件接收器,就有事件發送器。發送器的作用是 引發事件。發送器可以是應用程序中的另一個對象或程序集,在系統事件中,例如鼠標單擊或鍵盤按鍵, 發送器就是.NET運行庫。注意,事件的發送器並不知道接收器是誰。這就使事件非常有用。
現在,在事件接收器的某個地方有一個方法,它負責處理事件。在每次發生已註冊的事件時,就執行這個事件處理程序。此時就要使用委託了。由於發送器對接收器一無所知,所以無法設置兩者之間的引用類型,而是使用委託作爲中介。發送器定義接收器要使用的委託,接收器將事件處理程序註冊到事件中。連接事件處理程序的過程稱爲封裝事件。封裝 Click事件的簡單例子有助於說明這個過程。
public delegate void EventHandler(object sender, EventArgs e); //注意這個,這是事件委託
public Form1()
{
InitializeComponent();
buttonOne.Click += new
EventHandler(Button_Click);
}
在Visual
Studio中,注意在輸入+=運算符之後,就只需按下Tab鍵兩次,編輯器就會完成剩餘的輸入工作。在大多數情況下這很不錯。但在這個例子中,不使用默認的處理程序名,所以應自己輸入文本。
System.Windows.Forms.Button, Text: button1(這個是sender的內容)
我們已經學習了許多概念,但要在接收器中編寫的 代碼量是很小 的。記住,編寫事件接收器常常比編寫事件發送器要 頻繁得多。至少在 Windows用戶界面上,Microsoft已經編寫了所有需要的事件發送器 (它們都在.NET 基類中,在 Windows.Forms命名空間中)。
——————————————————————————————————————————————————————
——————————————————————————————————————————————————————
——————————————————————————————————————————————————————
——————————————————————————————————————————————————————
——————————————————————————————————————————————————————
——————————————————————————————————————————————————————
——————————————————————————————————————————————————————