1. 程式人生 > >C#高級編程第9版 閱讀筆記(一)

C#高級編程第9版 閱讀筆記(一)

mda 查找 弱引用 isp protect enume 前言 不支持 操作符

一、前言

C# 簡潔、類型安全的面向對象的語言。

.NET是一種在windows平臺上編程的架構——一種API。

C#是一種從頭開始設計的用於.NET的語言,他可以利用.NET Framework及其開發環境中的所有新增功能,面向對象的編程方法。

組件對象模型 COM Component Object Model

.NET的優點:面相對象編程,優秀的設計,語言無關,對動態Web頁面的更好支持,高效的數據訪問,代碼共享,增強的安全性,對安裝沒有任何影響,web服務的支持。

.net framework 1.0 2002年發布

.net framework 2.0 對泛型的支持、新類和接口

.net framework 3.0 引入創建UI的新方式(WPF和XAML,基於矢量的圖形替代了基於像素的圖形)

.net framework 4.0 提供了動態語言集成和大量用於並行編程的新庫

End Day 1 Page xix

第1章 .NET體系結構

1.1 C#與.NET的關系

1.2 公共語言運行庫

公共語言運行庫CLR 在CLR控制下運行的代碼稱為托管代碼

編譯的兩個階段:1、將源代碼編譯為Microsoft中間語言IL 2、CLR把IL編譯為平臺專用的代碼。

1.3中間語言

IL總是即時編譯的,稱為JIT編譯。

中間語言IL的主要特性:

a、面向對象和使用接口

用.NET建立的接口與COM接口共享一個理念:提供一個契約,實現給定接口的類必須提供該接口指定的方法和屬性的實現。

語言互操作性的真正含義是用一種語言編寫的類能直接用另一種語言編寫的類通信。特別是:

² 用一種語言編寫的類能繼承另一種語言編寫的類

² 一個類能包含另一個類的實例,而不管兩個類是使用什麽語言編寫的。

² 一個對象能直接調用其他語言編寫的另一個對象的方法

² 對象或對象的引用能在方法之間傳播

² 在不同的語言之間調用方法時,能在調試器中交替調試這些方法調用,即調試不同語言編寫的源代碼。

b、值類型和引用類型的顯著差異

值類型:變量直接存儲其數據 一般存儲在堆棧中

引用類型:變量僅存儲地址,對應的數據在該地址中找到 存儲在托管堆

c、強數據類型化

不允許對模糊的數據類型執行任何操作;

通用類型系統 CTS Common Tpye System

公共語言規範 CLS Common Language Specification

d、異常錯誤處理

e、特性的使用

1.4 程序集

程序集的兩種類型:私有程序及 共享程序集

1.5 .NET Framework類

.NET Framework 4.5基類大致包含一下範圍:

² IL提供的核心功能

² Windows UI支持和控件

² 在ASP.NET中使用Web窗體和MVC

² 使用ADO.NET和XML進行數據訪問

² 文件系統和註冊表訪問

² 網絡和Web瀏覽

² .NET特性和反射

² COM互操作性

1.6 命名空間

1.7 用C#創建.NET應用程序

創建Windows桌面應用程序的兩種技術:windows窗體和WPF Windows Presentation Foundation。前者只是封裝了原生windows空間,是基於像素圖形的。

WPF是基於矢量圖的。

WPF在創建應用程序時使用XAML。XAML 可擴展的應用程序標記語言eXtensible Application Markup Language

聲明性編程:不利用編程語言而是通過編程來創建對象,是通過XML類型的編程來聲明所有元素。

WCF是一種功能豐富的技術,提供了多重通信選項。記可以使用基於REST的通信,也可以使用基於SOAP的通信,都能獲得標準Web服務提供的所有功能。

1.8 C#在.NET企業體系結構中的作用

第2章 核心C#

2.4 預定義數據類型

值類型存儲在堆棧中,引用類型存儲在托管堆上。

C#有15個預定義類型,其中13個是值類型,2個是引用類型string和object

預定義整數類型8個:sbyte short int long byte ushort uint ulong

預定義浮點類型2個:float double

預定義decimal 不財務計算專用,不是基本類型

預定義bool類型:

預定義字符類型:char

預定義引用類型2個:object string

2.5 流控制

條件語句:if switch

循環語句:for while do…while foreach

跳轉語句:goto break continue return

2.6 枚舉

枚舉是用戶定義的整數類型,在聲明一個枚舉時,要指定該枚舉的實例可以包含的一組可接受的值。

End Page 46

2.7 名稱空間

2.8 Main()方法

2.9 有關編譯C#文件的更多內容

2.10 控制臺I/O

2.11 使用註釋

2.12 C#預處理器指令

預處理器指令的命令不會轉化為可執行代碼中的命令,但會影響編譯過程的各個方面。

2.13 C#編程規則

第3章 對象和類型

3.1 創建及使用類

3.2 類和結構

類和結構都是創建對象的模板,每個對象都包含數據,並提供了處理和訪問數據的方法。

類和結構的區別是他們在內存中的存儲方式、訪問方式。類是存儲在堆heap上的引用類型。結構是存儲在棧stack上的值類型。結構不支持繼承。較小的數據類型使用結構可以提高性能。

3.3 類

End Page 79

3.4 匿名類型 是一個只繼承自Object且沒有名稱的類

3.5 結構

結構總是派生自System.ValueType,System.ValueType派生自System.Object。

結構不支持繼承;不允許有無參的構造函數;可以指定字段如何在內存中布局。

結構主要用於小的數據結構。但當把結構作為參數傳遞給方法時,應把它作為ref參數傳遞,以避免性能損失——此時只傳遞了結構在內存中的地址。

3.6 弱引用

弱引用允許創建和使用對象,但是垃圾回收器運行時,就會回收對象並釋放內存。使用WeakReference類創建。

3.7 部分類

Partial關鍵字允許把類、結構、方法或接口放在多個文件中。

3.8 靜態類

靜態類在功能上與使用私有靜態函數創建的類相同,不能創建靜態類的實例。使用類型名即可進行靜態類的調用。

3.9 Object類

所有的.NET類都派生自System.Object。

3.10 擴展方法

擴展方法是靜態方法,它是類的一部分,但實際上沒有放在類的源代碼中。

第4章 繼承

4.1 繼承

4.2 繼承的類型

實現繼承:表示一個類型派生於一個基類型,它擁有該基類型的所有成員字段和函數。

接口繼承:表示一個類型只繼承了函數的簽名,沒有繼承任何實現代碼。

結構總是派生自System.ValueType,他們還可以派生自任意多個接口。

類總是派生自System.Object或用戶選擇的另一個類,它們還可以派生自任意多個接口。

4.3 實現繼承

如果簽名相同的方法在基類和派生類中都進行了聲明,但該方法沒有分別聲明為virtual和override,派生類方法就會隱藏基類方法。

C#中特殊的語法用於從派生類中調用方法的基類版本:base<MethodName>()

C#允許把類和函數聲明為abstrac。抽象類不能實例化,抽象函數不能直接實現,必須在非抽象的派生類中重寫。

C#允許把類和方法聲明為sealed。對於類,表示不能繼承該類;對於方法,表示不能重寫該方法。

構造函數的調用順序是先調用System.Ojdect,再按照層次結構由上向下進行,直到到達編譯器要實例化的類為止。

4.4 修飾符

public protected intermal private

new static virtual abstract override sealed extern

4.5 接口

聲明接口在語法上與聲明抽象類完全相同,但不允許提供接口中任何成員的實現方法。一般情況下,接口只包含方法、屬性、索引器和事件的聲明。

不能實例化接口,它只包含其成員的簽名。接口既不能有構造函數,也不能有字段。

在接口定義中不允許聲明關於成員的修飾符。接口成員總是公有的,不能聲明為虛擬或靜態。

End Page 119

第5章 泛型

5.1 泛型概述

泛型可以創建獨立於被包含類型的類和方法。

泛型類使用泛型類型,並可以根據需要用特定的類型替代泛型類型,保證了類型安全性。

泛型類、泛型接口、泛型方法、泛型委托。

值類型存儲在棧上,引用類型存儲在堆上。C#類是引用類型,結構是值類型。

引用類型共享同一個本地類的所有相同的實現代碼,這是因為引用類型在實例化的泛型類中只需要4個字節的內存地址(32位系統),就可以引用一個引用類型。值類型包含在實例化的泛型類的內存中,同時因為每個值類型對內存的要求都不高,所以要為每個值類型實例化一個新類。

5.2 創建泛型類

5.3 泛型類

默認值:根據泛型類型是引用類型還是值類型,泛型default用於將泛型類型初始化為null或0。

約束:如果泛型類需要調用泛型類型中的方法,就必須添加約束。

繼承:泛型類型可以實現泛型接口,也可以派生自一個類。

泛型類可以派生自泛型基類,其要求是必須重復接口的泛型類型或者必須指定基類的類型。

靜態成員:泛型類的靜態成員只能在類的一個實例中共享。

5.4 泛型接口

.NET 4通過協變和抗變為泛型接口和泛型委托添加了一個重要的擴展。

協變和抗變指對參數和返回值的類型進行轉換。

參數類型是協變的,方法的返回類型是抗變的。

如果泛型類型用out關鍵字標註,泛型接口就是協變的。

如果泛型類型用in關鍵字標註,泛型接口就是抗變的。

5.5 泛型結構

5.6 泛型方法

第6章 數組

6.1 同一類型和不同類型的多個對象

同一類型的多個對象可以使用集合和數組。不同類型的多個對象可以使用元組Tuple類型。

6.2 簡單數組

數組是引用類型,所以聲明了數組後,必須給它分配堆上的內存。

在指定了數組的大小後,如果不復制數組的所有元素,就不能重新設置數組的大小。如果事先不知道數組中應包含多少個元素,就可以使用集合。

6.3 多維數組

6.4 鋸齒數組

End Page 139

6.5 Array類

用方括號聲明數組是C#中使用Array類的表示法。

在後臺使用C#語法,會創建一個派生自抽象基類Array的新類。

Array類是一個抽象類,所以不能使用構造函數來創建數組。

如果數組的元素是值類型,復制數組就會復制所有值。

如果數組的元素是引用類型,則不復制元素,而只復制引用。

6.6 數組作為參數

數組支持協變,這表示數組可以聲明為基類,其派生類型的元素可以賦予數組元素。

數組協變只能用於引用類型,不能用於值類型。

ArraySegment<T>表示數組的一段,此結構包含關於數組段的信息(偏移量和元素個數)。

數組段不復制原數組的元素,但是原數組可以通過ArraySegment<T>訪問。如果數組段中的元素改變了,這些變化就會反映到原數組中。

6.7 枚舉

在foreach語句中使用枚舉,可以叠代集合中的元素,且無須知道集合中的元素個數。

數組或集合實現帶GetEumerator()方法的IEumerable接口。GetEumerator()方法返回一個實現IEumerable接口的枚舉,接著,foreach語句就可以使用IEumerable接口叠代集合了。

yield語句用於創建枚舉器。yield return語句返回集合的一個元素,並移動到下一個元素上。yield break可停止叠代。包含yield語句的方法或屬性也稱為叠代塊,叠代塊必須聲明為返回IEnumerator或IEnumerator接口,或者這些接口的泛型版本。這哥塊可以包含多條yield return語句或yield break語句,但不能包含return。

6.8 元組

.NET Framework定義了8個泛型Tuple類和一個靜態Tuple類,他們用作元組的工廠。

6.9 結構比較

第7章 運算符和類型強制轉換

7.1 運算符和類型轉換

7.2 運算符

7.3 類型的安全性

7.4 比較對象的相等性

End Page 169 Start 2017年10月8日

7.5 運算符重載 operator

C#要求所有的運算符重載都要聲明為public和static。

C#要求必須成對重載比較運算符,且必須返回布爾類型的值。==和!= >和< >=和<= 三對。

7.6 用戶定義的類型強制轉換

隱式Implicit強制轉換、顯式Explicit強制轉換

C#要求把類型強制轉換的定義放在源類(或結構)或目標類(或結構)的內部。

End Page 189 Start 2017年10月9日

第8章 委托、lambda表達式和事件

8.1 引用方法

委托是類型安全的類,她定義了返回類型和參數的類型。

委托不僅包含對方法的引用,也可以包含對對歌方法的引用。

8.2 委托

在C#中,委托在語法上總是接受一個參數的構造函數,這個參數就是委托引用的方法。這個方法必須匹配最初定義委托時的簽名。

為了減少輸入量,只要需要委托實例,就可以只傳送地址的名稱,這稱為委托推新。只要編譯器可以把委托實例解析為特定的類型,這個C#特性就是有效的。

給定委托的實例可以引用任何類型的任何對象上的實例方法或靜態方法——只要方法的簽名匹配與委托的簽名即可。

泛型Action<T>委托允許調用void返回類型的方法。

泛型Func<T>委托允許調用帶返回類型的方法。

多播委托:按順序連續調用多個方法,委托的簽名必須返回void。

8.3 lambda表達式

8.4 事件

第9章 字符串和正則表達式

9.1 字符串

9.2 正則表達式:專門用於字符串處理的語言,一組用於標識字符類型的轉義代碼。

第10章 集合

10.2 集合接口和類型

10.3 列表 List<T>

10.4 隊列 先進先出 Queue<T>

10.5 棧 後進先出 Stack<T>

10.6 鏈表 雙向鏈表 LinkedList<T>

10.7 有序列表 基於鍵對所需集合排序 SortedList<TKey,TValue>類

10.8 字典 也稱為映射或散列表 根據鍵快速查找值 Didtionary<TKey,TValue>

Lookup<TKey,TElement> SortedDictionary<TKey,TValue>

10.9 集 HastSet<T>不重復元素的無序列表 SortedSet<T>不重復元素的有序列表

10.10 可觀察的集合 ObservableCollecton<T>

10.11 位數組

BitArry類引用類型,可以重新設置大小

BitVector32結構 值類型,是基於棧的,速度快。

10.12 不變的集合 Immutable.Collections

10.13 並發集合 Collections.Concurrent

10.14 性能

End Page 286

第11章 LINQ

11.1 LINQ概述 語言集成查詢Language Integrated Query

查詢表達式必須以from子句開頭,以select或group子句結束,在這兩個子句之間可以使用where、orderby、join、let和其他from子句。

在運行期間定義查詢表達式時,查詢不會運行,查詢會在叠代數據項時運行。

11.2 標準的查詢操作符

Where() 傳遞第二個參數索引,索引是篩選器返回的每個結果的計數器。

OfType() 基於類型的篩選

GroupBy()

11.3 並行LINQ

11.4 表達式樹

11.5 LINQ提供程序

第12章 動態語言擴展

12.1 DLR Dynamic Language Runtime 動態語言運行時

12.2 dynamic類型 允許編寫忽略編譯期間的類型檢查的代碼

對於dynamic類型有兩個限制。動態對象不支持擴展方法,匿名函數Lambda表達式也不能用做動態方法調用的參數,因此LINQ不能用於動態對象。大多數LINQ調用都說擴展方法,而Lambda表達式用作這些擴展方法的參數。

12.3 包含DLR ScriptRuntime

12.4 DynamicObject和ExpandoObject

End Page 332

第13章 異步編程

13.1 異步編程的重要性

C#5.0最重要的改進是提供了更強大的異步編程。新增兩個關鍵字:async和await。

異步編程的方法調用是在後臺運行(通常在線程或任務的幫助下)並且不會阻塞調用線程。

三種不同模式的異步編程:異步模式、基於事件的異步模式、基於任務的異步模式TAP。

新增的基於任務的異步模式TAP 是利用asynv和await關鍵字實現的。

13.2 異步模式

異步模式定義了BeginXXX方法和EndXXX方法。BeginXXX方法接受其同步方法的所有輸入參數,EndXXX方法使用同步方法的所有輸出參數,並按照同步方法的返回來型來返回結果。

使用異步模式時,BeginXXX方法定義了一個AsyncCallbak參數,用於接受在異步方法執行完成後調用的委托。BeginXXX方法返回IAsyncResult,用於驗證調用是否已經完成,並且一直等到方法的執行結束。

基於事件的異步編程定義了一個帶有Async後綴的方法。異步方法完成時,不是定義要調用的委托,而是定義一個事件。

基於任務的異步編程定義了一個帶有Async後綴的方法,並返回一個Task類型。但是不需要生聲明Task類型的變量來設置方法返回的結果。只要聲明一個String類型的變量,並使用await關鍵字。await關鍵字會解除線程的阻塞,完成其他任務。

13.3 異步編程的基礎

async和await關鍵字只是編譯器功能。編譯器會用Task類創建代碼。

Async修飾符只能用與返回Task或void的方法,不能用於程序的入口點,即Main方法不能使用async修飾符。await只能用於返回Task方法。

組合器:一個組合器可以接受多個同一類型的參數,並返回同一類型的值,多個同一類型的參數被組合成一個參數來傳遞。Task組合器接受多個Task對象作為參數,並返回一個Task。

13.4 錯誤處理

13.5 取消

第14章 內存管理和指針

14.1 內存管理

14.2 後臺內存管理

棧存儲不是對象成員的值數據類型。棧是向下填充的,即從高內存地址向低內存地址填充。

棧指針表示棧中下一個空閑存儲單元的地址。

14.3 釋放非托管的資源

在定義一個類時,可以使用兩種機制來自動釋放非托管的資源。一種是聲明一個析構函數或終結器,作為類的一個成員。另一種是在類中實現System.IDisposable接口。

14.4 不安全的代碼

第15章 反射

15.1 在運行期間處理和檢查代碼

自定義特性允許把自定義元數據與程序元素關聯起來,這些元數據是在編譯過程中創建的,

並嵌入到程序集中。

反射是一個普通術語,它描述了在運行過程中檢查和處理程序元素的功能。

15.2 自定義特性

特性類Attribute本身用一個特性——System.AttributeUsage特性來標記。

AttributeUsage更像一個元特性,因為它只能應用到其他特性上,不能應用到類上。

15.3 反射

System.Type:訪問關於任何數據類型的信息。

System.Reflenction.Assembly:訪問給定程序集的相關信息或者把程序集加載到程序中。

獲取指向任何給定類型的Type引用有三種方法,具體如下:

Typeof(給定類型) Type t=給定類型.GetType() Type t=Type.GetType(給定類型)

Type是許多反射功能的入口,實現許多方法和屬性。

第16章 錯誤和異常

16.1 簡介

16.2 異常類

16.3 捕獲異常

16.4 用戶定義的異常類

16.5 調用者信息

End Page 418

C#高級編程第9版 閱讀筆記(一)