一、C#和.NET框架
CIL(Common Intermediate Language)公共中間語言
CLR(Common Language Runtime)公共語言運行庫
BCL(Base Class Library)基類庫
JIT(Just-in-Time)編譯器
managed code托管代碼
.NET框架由兩部分組成:公共語言運行庫和基類庫,即CLR和FCL(框架類庫,是BCL的超集,包括Windows Forms、ASP.NET LINQ以及更多命名空間)。
CLR在運行期管理程序的執行:內存管理、代碼安全驗證、代碼執行、垃圾收集。
BCL和FCL包括:通用基礎類(比如字符串操作、安全和加密)、集合類(實現列表、字典、散列表以及位數組)、線程和同步類(創建多線程)、XML類(用於創建、讀取以及操作XML文檔)
.NET語言編譯器接受源代碼文件,並生成程序集的輸出文件。程序集可以是可執行文件或DLl。程序集里的代碼不是本機代碼,而是CIL公共中間語言。
程序CIL直到調用運行時才會被編譯成本機代碼。在運行時,CLR執行:
檢查程序集的安全特性、在內存中分配空間、把程序集的可執行代碼發送給JIT編譯器,把其中的一部分編譯成本機代碼。
- 托管代碼:為.NET框架編寫的代碼
- 非托管代碼:不在CLR控制之下運行的代碼,比如Win32C/C++ DLL
.NET框架的核心組件是CLR,在操作系統的頂層並管理程序的執行。並提供下列服務:自動垃圾收集、安全和認證、通過訪問BCL得到廣泛編程功能。
二、C#編程概述
三、類型、存儲和變量
C程序是一組函數和數據類型,
C++程序是一組函數和類,
C#是一組類型聲明。類型聲明包括:名稱、結構、行為。
- 值類型:只需要一段單獨的內存,用於存儲實際的數據,可以在堆也可以在棧。
- 引用類型:需要兩段內存:一段存儲實際的數據,始終位於堆中;二段是一個引用,指向數據在堆中的存放位置。
對於引用類型的任何對象,它所有的數據成員都存放在堆里,無論它是值類型還是引用類型。
四、類:基礎
訪問修飾符:私有(private)、公有(public)、保護(proteced)、內部(internal)、受保護內部(proteced internal)
五、方法
常量const:聲明中必須初始化;聲明后不能改變。
ref:引用與實參相同的內存位置,即傳進去的是地址,會改變值。
out:要先賦值,然后在方法里對該地址的值進行改變。
params:參數數組,允許多個實參對應一個特殊的形參。
六、類進階
const修飾符:只能在字段聲明語句中初始化,值在編譯期決定
readonly修飾符:可以在任意位置初始化,值在運行期決定
this關鍵字:在類中使用,是對當前實例的引用,靜態成員不是實例的一部分,所以靜態函數成員不能使用this。
this被用於下列目的:區分類的成員和本地變量,或參數;作為調用方法的實參。
七、類和繼承
除了類object,所有的類都是派生類。訪問基類用關鍵字base.
派生類的實例由基類的實例加上派生類附加的成員組成。派生類的引用指向整個類對象,包括基類部分。
當使用基類引用訪問派生類對象時,得到的是基類的成員。虛方法可以使基類的引用訪問派生類內。virtual override
派生類使用一個指定的基類構造函數而不是無參構造函數,必須在構造函數初始化語句中指定它:1、使用關鍵字base,2、使用關鍵字this。
public myClass(int x):base(s,x)
myClass() 等價於 myClass():base()
程序集指該命名空間namespace
抽象類:只能被用作其它類的基類,就是被設計來被繼承的。不能創建抽象類的實例;用abstract修飾符聲明;可以派生自另一個抽象類;派生自抽象類的類必須使用override實現該類所有的抽象成員。
密封類:只能被用作獨立的類,不能被用作基類;用sealed修飾符。
靜態類:用static修飾符;所有成員必須是靜態;是密封的;
外部方法:external method是在聲明中沒有實現的方法,常常是c#之外的語言編寫的。
八、表達式和運算符
無后綴的實數字面量是double類型,不是float類型。
typeof運算符:Type t = typeof(someClass),Type是System命名空間中的一個類。t.GetFields()獲取變量列表;t.GetMethods()獲取方法列表;GetType().Name獲取類的名字。
九:語句
break:跳出最內層封裝的語句
continue:轉到最內層封裝循環的頂端
using:某些類型的非托管對象有數量限制或很耗費系統資源,using可以確保這些資源被適當地處置。資源是一個實現System.IDisposable接口的類或結構。Dispose方法:分配資源、使用資源、處置資源。
using會隱式產生try,finally,塊。在finally中會調用Dispose來處置資源。
十、命名空間和程序集
程序集:不包括本地機器代碼,而是公共中間語言代碼。包含實時編譯器JIT在運行時轉換CIL到本機代碼所需的一切,包括對它所引用的其它程序集的引用。程序集的文件擴展名通常為.exe或.dll。
十一、異常
十二、結構
結構:是值類型,類是引用類型;結構是隱式密封的,所以不能被派生。
十三、枚舉
枚舉:是值類型,命名的整數值常量。
十四、數組
數組:是引用類型,由一個變量名稱表示的一組同類型的數據元素。一旦被創建,大小就固定,C#不支持動態數組。
數組實例是從System.Array繼承的對象。數組是引用類型,但是數組元素可以是值類型或引用類型。
3×3的矩形數組以及一個由三個長度為3的一維數組構成的交錯數組的結構。
1、兩個數組都保存了9個整數,但是它們的結構卻很不相同。
2、矩形數組只有單個數組對象,而交錯數組有4個數組對象。
foreach:迭代變量是臨時的,只讀的,並且和數組中元素的類型相同。
Clone:為數組進行淺復制,克隆值類型數組會產生兩個獨立數組;克隆引用類型數組會產生指向相同對象的兩個數組類型。
十五:委托
委托:delegate可以認為是包含具有相同簽名和返回值類型的有序方法列表,當委托被調用時,它調用列表中的每一個方法。委托是面向對象的並且是類型安全的。
調用列表中的方法可以是實例或是靜態方法。
調用委托可以像調用方法一樣,最后一個方法執行的返回值是委托返回的值
匿名方法轉換成lambda表達式
十六、事件
事件event:與委托相似,事件就好像被簡化的針對特殊用途的委托。注冊到事件上的方法會在事件觸發時被調用。事件包含一個私有的委托。
觸發(raise)事件:調用(invoke)或觸發(fire)事件。
十七、接口
接口interface:引用類型,表示一組函數成員而不實現成員的引用類型,類和結構可以實現接口。接口可以多繼承,類只能單繼承。
從類對象引用獲取接口引用,然后使用接口引用調用方法。用as來獲取。
十八、轉換
轉換conversion:聲明兩個不同類型的變量,然后把一個變量(源)的值賦值給另外一個變量(目標)。
隱式轉換:不會丟失數據或精度
顯式轉換:可能會引起丟失數據
裝箱:把引用類型轉換到object,把值類型轉換到System.ValueType
裝箱:在堆分配好內存;將值類型字段復制到堆內存中;返回對象的地址,也就是對象的引用。
返回了副本的值的引用類型,裝箱后,有兩份值-原始值類型和副本的引用類型。
拆箱:顯式轉換,把裝箱后的對象轉換回值類型的過程。檢測到要拆箱的對象實際是ValueType的裝箱值,把對象的值復制到變量。
值類型轉換:
占據較少位的可以隱式轉換為多位的數字類型
unchecked:會忽略溢出
checked:拋出OverflowException異常
引用類型轉換:
is 運算符:來檢查轉換是否會成功完成。只可以用於引用轉換以及裝箱和拆箱轉換。
as運算符:和強制轉換運算符類似,如果轉換失敗,把目標引用設置為null而不是拋出異常。只能用於引用轉換和裝箱轉換。不支持用戶自定義或值類型的轉換。
十九:泛型
泛型:不是類型,而是類型的模板。C#提供5種泛型:類、結構、接口、委托和方法。
泛型和非泛型區別:
Where:約束泛型的范圍。
二十:枚舉數和迭代器
數組可以迭代是因為數組可以按需提供一個枚舉數的對象,枚舉數可以依次返回請求的數組的元素。枚舉數“知道”項的次序並且跟蹤它在序列中的位置,然后返回請求的當前項。
foreach結構被設計和可枚舉類型一起使用。
枚舉數類型:IEnumerator/IEnumerable接口 非泛型接口
IEnumerator<T>/IEnumerable<T>接口 泛型接口
IEnumerator接口包含三個函數成員: Current、 MoveNext以及Reset。
Current返回序列中當前位置項的屬性。
MoveNext是把枚舉數位置前進到集合中下一項的方法。它也返回布爾值,指示新的位置是有效位置或已經超過了序列的尾部。
Reset方法把位置重置為原始狀態。
二十一:介紹LINQ
Linq(Language Integrated Query語言集成查詢)是集成到C#和Visual Basic.NET這些語言中用於提供查詢數據能力的一個新特性。是.NET框架的擴展,允許我們以數據庫查詢的方式查詢數據集合。C#3.0引入。
XML
二十二、異步編程簡介
啟動一個程序時,系統在內存中創建一個新的進程(process)。
進程:就是一組資源,構成了一個正在運行的程序。這些資源包括虛擬地址空間、文件句柄以及程序啟動需要的其它東西的載體。
線程:在進程中,系統創建一個叫線程(thread)的內核對象,體現了一個程序的真實執行情況。一旦程序准備完畢,系統在線程中開始執行Main方法的第一條語句。
線程重要事項:
1、默認情況下,一個進程只包含一個線程,從程序開始到結束
2、一個線程可以發起另外一個線程,一個進程可能在不同狀態有多個線程來執行程序不同部分
3、如果一個進程中有多個線程,它們會分享進程的資源
4、線程是由系統負責調度的處理器(而不是進程)上的執行單元
同步編程:程序的進程只有一個線程,並且語句是順序執行的
異步編程:程序發起多個線程,理論上是同一個時間執行的(其實不一定真的在同一時間執行)
在多核處理器的系統,不同線程可能在不同的處理器上同時執行,可以提高性能。
多線程處理:增加程序的負荷和額外復雜度。例如:
1、創建和銷毀線程都有時間和資源的成本
2、安排線程、把它們加載到處理器中以及每次時間片段之后保存狀態都需要時間
3、由於進程中的線程共享相同的資源和堆,需要增加額外的編程復雜度來確保它們之間不相干擾
4、調試多線程非常困難,因為程序每次運行的時間不同可能會產生不同的結果
多線程處理復雜度:
1、線程之間通信:同一進程的所有線程來說,內存是可見也是可訪問的
2、協調線程:線程之間的執行順序
3、同步資源使用:進程內所有線程共享相同的資源和內存,要確保不同線程沒有同一時間訪問和改變它們引起沖突的狀態
C#中委托就是一個簡單的機制用於異步執行方法。運用BeginInvoke,EndInvoke實現異步執行。有下面三種用法:
二十三、預處理指令
源代碼指定了程序的定義。預處理指令(preprocessor directive)指示編譯器如何處理源代碼。
二十四、反射和特性
大多數程序是用來處理數據的,讀、寫、操作和顯示數據,而有時候操作的數據不是數字、文本或圖形,而是程序和程序類型本身的信息。
1、有關程序及其類型的數據稱為元數據(metadata),它們保存在程序的程序集中。
2、程序在運行時,可以查看其它程序集或其本身的元數據,這個查看行為就叫反射。
Type抽象類,被設計用來包含類型的特性,使用這個類的對象能獲取程序使用的類型的信息。創建一個類時,CLR會創建一個Type抽象類的對象。
Type對象的獲取:使用GetType方法和 typeof運算符
特性(attribute)是一種允許我們向程序的程序集增加元數據的語言。它是用於保存程序結構信息的某種特殊類型的類。
特性的目的是告訴編譯器把程序結構的某組元數據嵌入程序集。
二十五:其它主題
1、字符串:是Unicode字符串數組,是不可變的(immutable)不能被修改。
對於一個string任何“改變”都會分配一個新的恆定字符串。
StringBuilder:可以產生能被修改的字符串,是Unicode字符的可變數組。會分配一個比當前字符串長度更長的緩沖區,只要能容納就不會分配新的內存。如果空間不夠,就分配更大的緩沖區,並把字符串拷貝到其中。