1..NET框架的組成
.NET框架由三部分組成(嚴格來說只有(框架類庫)兩部分),如圖
執行環境稱為:CLR(公共語言運行庫),它在運行期管理程序的執行.
BCL(基類庫)是.NET框架使用的一個大的類庫.它包含以下這些類
通用基礎類,集合類,線程和同步類,XML類.
2.編譯成CIL
CIL(公共中間語言):一旦CIL被編譯成本機代碼,CLR就在它運行時管理它,執行像釋放無主內存,檢查數組邊界,檢查參數類型和管理異常之類的任務.
3.托管代碼與非托管代碼
非托管代碼:不在CLR控制之下運行的代碼,比如WIN32 C/C++ DLL,稱為非托管代碼
4.CLR
CLR是.NET框架的核心組件,它在操作系統的頂層,負責管理程序和執行.
CLR還提供以下服務:
自動垃圾收集
安全和認證
通過訪問BCL得到廣泛的編程功能,包括和WEB服務和數據服務之類的功能.
5.CLI
CLI(公共語言基礎結構)是一組標准,它把所有的.NET框架的組件連結成一個內聚的,一致的系統.它展示了系統的概念和架構.並詳細說明了所有軟件都必須堅持的規則和約定.
其中,CTS和CLS是CLI的重要組成部分
6.
1.標識符與關鍵字
區分大小寫,注意@字符
2.輸出語法
eg:
Console.WriteLine(,,)
3.注釋
1.預定義類型
有16種,其中13種簡單類型,3中非簡單類型
decimal:小數類型的有效數字為28位
dynamic:在使用動態語言編寫的程序集時使用
2.用戶定義類型
有6種類型可以由用戶自己創建.它們是
3.
運行中的程序使用兩個內存區域來存儲數據:棧和堆
棧是一個內存數組,是一個LIFO(後進先出)的數據結構
堆是一塊內存區域,在堆裡可以分配大塊的內存用於存儲某類型的數據對象.
4.值類型和引用類型
值類型只需要一段單獨的內存,用於存儲實際的數據.
引用類型需要兩段內存:第一段存儲實際的數據,它總是在堆中;第二段是一個引用,指向數據在堆中的存放位置.
對於引用類型的任何對象,它所有的數據成員都存放在堆裡,無論它們是值類型還是引用類型.
5.C#類型的分類
6.靜態類型和dynamic關鍵字
靜態類型:變量的類型在編譯的時候確定並且不能在運行時修改.
dynamic關鍵字:代表一個特定的,實際的C#類型,它知道如何在運行時解析自身,也就是說,它是動態化的靜態類型.
7.可空類型
可空類型允許創建可以標記為有效或無效的值類型,這樣就可以在使用它之前確定值的有效性.普通的值類型稱作非可空類型
①創建可空類型
eg:
int myNInt ;
1.為數據分配內存
要為實際數據分配內存,需要使用new運算符.
new運算符為任意指定類型的實例分配並初始化內存.它依據類型的不同從棧或堆裡分配
2.訪問修飾符
5種
1.
字段通常保存和對象狀態有關的數據.
本地變量通常用於保存本地的或臨時的計算數據.
2.var關鍵字
var關鍵字並不是某種特別類型的符號,它只是句法上的速記,表示任何可以從初始化的右邊推斷出的類型.
var關鍵字的一些重要的條件:
①.
②.只能在變量聲明中包含初始化時使用;
③.一旦編輯器推斷出變量的類型,它就是固定且不能更改的.
3.本地常量
關鍵字const
兩個特征:
①.常量在聲明中必須初始化
②.常量在聲明後不能改變.
③.只能被聲明在類聲明中.
④常量沒有自己的存儲位置,而是在編譯時被編譯器替換.類似於C++中的#define值
eg:
int
4.返回值
經測試,聲明了返回類型的方法必須使用return語句從方法返回一個值,返回值的類型應與聲明返回類型一致或可以隱性轉換.
不返回類型的方法可以使用void聲明方法.
return;這種不帶參數的形式的返回語句只能用於聲明void類型的方法.
5.引用參數
①使用引用參數時,
②,如果是引用類型變量,可以賦值為一個引用或null值.
③引用參數的實參與形參用的是相同的內存,而值參數的實參與形參不是用相同內存.
eg:
過程:
6.輸出參數
關鍵字out
①必須在聲明和調用中都使用修飾符,輸出參數的修飾符是out.
②實參必須是變量.
③在方法內部,輸出參數在被讀取之前必須被賦值,這意味著參數的初始值是無關的,而且沒有比要像ref一樣在方法調用之前為實參賦值.
eg:
過程:
7.
①它允許零個或多個實參對應一個特殊的形參.
②在一個參數列表中只能有一個參數數組.
③如果有,它必須是列表中的最後一個.
④聲明參數數組時在數據類型前需要使用params修飾符,在數據類型後放置一組空的方括號.調用時不允許有params修飾符.
⑤參數數組的方法調用,可以一個逗號分隔該數據類型元素的列表,也可以是該數據類型元素的一維數組.
⑥當實參是一維數組時,編輯器是使用這組數組而不是重新創建一個.
eg:列表作實參;
過程:
eg:數組作實參
8.參數類型總結
9.方法重載
一個類中可以有一個以上的方法擁有相同的名稱,這叫做方法重載
使用相同名稱的每個方法必須有一個和其他方法不相同的簽名,可以為:
●方法的名稱;
●參數的數目;
●參數的數據類型和順序;
●參數修飾符;
注意:
10.命名參數
從C#4.0開始,只要顯式指定參數的名字,就可以任意順序在方法調用中列出實參.
eg:使用命名參數的結構
eg:如果是參數順序不同的重載,使用命名參數則會報錯.
partialclass : System.Web.UI.
Page_Load( sender, e)
my = ();
a = my.s(b:4,a:4);
s( a, b)
s = 0;
s;
s( b, a)
s = 0;
s;
11.可選參數
所謂可選參數就是在調用方法的時候包含這個參數,也可以忽略它.
可選參數只能是值參數類型
eg:
1.靜態字段/靜態成員
關鍵字static
靜態字段被類的所有實例共享,所有實例都訪問同一內存位置.
實例不能訪問靜態成員,因為靜態成員不屬於某一對象,它只屬於類本身.
2.屬性
屬性是一個函數成員,它不為數據存儲分配內存,它執行代碼.
屬性是指定的一組兩個匹配的,稱為訪問器的方法.
set訪問器用於為屬性賦值.
get訪問器用於從屬性取值.
屬性也可以聲明為static.靜態屬性的訪問器和所有靜態成員一樣,不能訪問類的實例成員,不管類是否有實例,它們都存在,還有從類外部訪問時,必須使用類名引用.
3.構造函數
4.靜態構造函數
①.靜態構造函數聲明中使用static關鍵字
②.
③.靜態構造函數不能有訪問修飾符.
④.
5.對象初始化
eg:
6.析構函數
析構函數執行在類的實例被銷毀之前需要清理或釋放非托管資源的行為.
每個類只能有一個析構函數.
析構函數只對類的實例起作用,因此沒有靜態析構函數.
不能在代碼中顯式調用析構函數.
一般不要用,占性能
7.Dispose
在類中實現名稱為IDisposable的接口,接口中把資源的清理代碼封裝在一個void類型的無參數方法中,就是Dispose()方法.
因為是Dispose做清理而不是析構函數,所以它應當調用)方法,該方法告訴CLR不要調用該方法的析構函數,因為它已經被清理了.
如下:
8.
類似於const修飾符,一旦值被設定就不能改變.不過有區別
①const字段只能在字段的聲明語句中初始化,而readonly字段在下列任意位置設置它的值.
●字段聲明語句中,這點同const
●類的任何構造函數.如果是static字段,初始化必須在static構造函數中完成.
②const字段的值必須在編譯期決定,而readonly字段的值可以在運行期決定.這種增加的自由性允許你在不同的環境或不同的構造函數中設置不同的值.
③與const不同,const總是像靜態的,而對於readonly字段,它可以使實例字段,也可以是靜態字段.而且它在內存中有存儲位置.
eg:
9.this關鍵字
this關鍵字在類中使用,是對當前實例的引用.它只能被用在下列類成員的代碼塊中.
●實例構造函數
●實例方法
●屬性和索引的實例訪問器
不能用在任何靜態成員中.this被用於下列目的:
●用於區分類的成員和本地變量,或參數;
●作為調用方法的實參.
10.索引
索引是一組get和set訪問器,類似於屬性的訪問器.
索引沒有名稱,在名稱位置是關鍵字this.參數列表在方括號中間.參數列表中至少必須聲明一個參數
索引還可以重載,類中重載的索引必須有不同的參數列表.
eg:
class
Lastname;
FirstName;
CityOfBirth;
[ index]
(index)
0: Lastname=;;
1: FirstName = ;;
2: CityOfBirth = ; ;
: ();
(index)
0: Lastname;
1: FirstName;
2: CityOfBirth;
: ();
11.分部類和分部類型
關鍵字partial
每個分部類的聲明都含有一些類成員的聲明.
類的分部類聲明可以在同一文件中也可以在不同文件中.
分部方法的例子
eg:
1.隱藏基類的成員
使用new關鍵字以顯式地告訴編譯器掩蓋基類成員.但如果要訪問被隱藏的基類成員,可以使用base表達式來訪問.
2.使用基類的引用
如果有一個派生類對象的引用,就可以獲取該對象基類部分的引用,使用類型轉換運算符把該引用轉換為基類類型.
eg:
3.
當使用基類引用訪問派生類對象時,得到的是基類的成員.虛方法可以使用基類的引用訪問"升至"派生類內
可以使用基類引用派生類的方法,要滿足下面條件
●派生類方法和基類方法有相同的簽名和返回類型
●基類的方法使用virtual標注
●派生類方法使用override標注
其他關於virtual和override修飾符的重要信息如下
●覆寫和被覆寫的方法必須有相同的可訪問性,換一種說法,被覆寫的方法不能是private等,而覆寫方法是public
●不能覆寫static方法或非虛方法.
●繼承的繼承可以覆寫override方法
eg:
4.繼承的繼承
eg:
如圖:SecondDerived類中是new了一個print方法,當執行MyBaseClass mybc = (MyBaseClass)derived;時,方法調用只向上傳遞了一級而已,因為SecondDerived類中的print方法是new的
所以輸出結果為:
如果把SecondDerived類中的print方法的new改成override,則結果為:
5.構造函數初始化語句
如果希望派生類使用一個指定的基類構造函數而不是無參數的構造函數,則必須在構造函數初始化語句中指定它,使用base關鍵字,見圖
如果希望調用同一類中的另一個構造函數,可以使用this關鍵字,見圖
6.類的可訪問性
對類的可訪問性,只有兩種修飾符:internal和public.(其他修飾符使類沒有訪問性)
標記為public的類可以被系統內任何程序集中的代碼訪問,
而標記為internal的類只能被它自己所在的程序集內的類看到.這是默認的訪問級別.
7.成員訪問修飾符
8,抽象成員
抽象成員是被設計來被覆寫的函數成員.
●它被用修飾符標記.
●它沒有實現代碼塊,抽象成員的代碼塊用分號表示.
●抽象成員只能在抽象類中聲明
●盡管抽象成員必須在派生類中用相應的成員覆寫,但不能把virtual修飾符附加到abstract修飾符.
●就想虛成員,派生類中抽象成員的實現必須指定override修飾符.
比較虛成員與抽象成員
9.
抽象類就是被設計來被繼承的,抽象類只能被用作其他類的基類
●
●抽象類使用abstract修飾符聲明
●抽象類可以包含抽象成員或普通的非抽象成員.
●
eg:數據成員不可以聲明為abstract
10.密封類
●密封類只能被用作獨立的類,不能被用作基類
●密封類使用sealed修飾符標注
11.
●
●靜態類本身必須標記為static
●靜態類可以有一個靜態構造函數,但沒有實例構造函數,不能創建該類的實例
●
eg:
12.
當一個類既是密封的(即不能繼承)又不能修改的情況下,可以使用擴展方法給該類添加方法.
●聲明擴展方法的類必須聲明為static
●擴展方法本身必須聲明為static
●擴展方法必須包含關鍵字this作為它的第一個參數類型,並在後面跟著它所擴展的類的名稱
●擴展方法的結構
eg:
1.數字不具有布爾意義
2.淺比較與深比較
①淺比較:如果引用相等,也就是說,如果它們指向內存中相同對象,那麼相等性比較為true,否則返回false,即使內存中兩個分離的對象在所有其他方面都完全相等也為false
②深比較:如果兩個字符串有相同的長度和相同的大小寫敏感的內容,那麼相等性比較返回true,即使它們占用不同的內存區域.
3.邏輯運算符
4.
①隱式轉換語法如下:
eg:
②顯式轉換語法:
只要將隱式轉換語法中的implicit替換為explicit
eg:
5.運算符重載
與用戶定義隱式轉換和顯式轉換類似.
只有以下這些運算符可以被重載.
eg:重載負數,減法和加法
6.typeof運算符