C#图解教程
基礎
1、virtual和new
? -?Virtual 關鍵字允許在派生類中重寫這些對象,默認情況下,方法是非虛擬的,不可以重寫非虛方法;
-?virtual關鍵字不可以與static、abstract、private、override一起使用。
-?Virtual關鍵字又是和override緊密不可分的,如果要實現Virtual方法就必須要使用override或new關鍵字(new和override產生的機理不同)。New和Override這兩個關鍵字是互斥的。不可以同時使用;
- new :?new關鍵字可以在派生類中隱藏基類的方法
- virtual:?Override關鍵字主要是提供派生類對基類方法的新實現,重寫的基類方法必須和Override的方法具有相同的簽名,相同的訪問修飾符
總結:New關鍵字主要用來區別派生類和基類同名方法的選擇問題,通過隱藏基類方法,達到使編譯器調用正確的方法的目的。Override主要用來對基類的方法和虛方法進行重寫。
2、不用vs軟件寫代碼
- 在notepad++ 中寫代碼,命名為.cs結尾的文件:My.cs
- 對源文件運行C#命令行編譯器csc.exe ,編譯(csc My.cs)→ 運行(My.exe)
- 打開命令行的方法:1、cmd中運行批處理文件【C:\Program Files (x86)\Microsoft Visual Studio\Preview\Enterprise\Common7\Tools\VsDevCmd.bat】,然后再轉到d: 盤 csc My.cs ;?
? ? ?2、在windows→?菜單→?開始→?程序→ VS菜單→ 命令提示符窗口
注: cmd中,d:轉到d盤目錄下, cd MyNote轉到d盤的MyNote目錄下
using System; namespace Wrox {public class My{static void Main(){Console.WriteLine("Hello form Wrox");Console.ReadLine();}} }?
回到頂部/編輯
* net框架
- .NET框架由三部分組成。
? ? ? ? ? ? ??
1.CLR
? ? ? ? ? ? ? ?* 內存管理和垃圾收集。
* 代碼安全驗證。
* 代碼執行、線程管理及異常處理。
- .NET Framework的核心是運行庫執行環境,稱為(公共語言運行庫CLR或.NET運行庫),通過CLR控制下運行的代碼稱為托管代碼
1.1 編譯:
1. 將源代碼編譯為Microsoft中間語言(IL)【低級語言,數字代碼,可快速轉換為本地機器碼】
2. CLR把IL編譯為平臺專用的代碼
- 優點:
平臺無關性:編譯為中間語言可以獲得.NET平臺無關性。
提高性能:IL總是即時編譯(稱為JIT編譯),只編譯調用的那部分,代碼編譯過一次后,得到的本地可執行程序就存儲起來,直到退出程序為止,下次運行著代碼就不需要重新編譯了。
托管IL代碼幾乎和本地機器代碼的執行速度一樣快,JIT編譯器確切知道程序運行在什么類型的處理器上,可以利用該處理器提供的任何特性或特定的機器代碼指令來優化最后
的可執行代碼。
語言的互操作性:能將VB C# C++編譯為中間語言,編譯為中間語言的代碼可以與其他語言編譯過來的代碼進行交互操作。
?
1.2 編譯工具涵蓋了編碼和調試所需的一切,包括:
* Visual Studio集成開發環境IDE.
* .NET兼容的編譯器(如:C#\ VB...).
* 調試器.
* 網站開發服務器技術,如ASP.NET 或WCF
BCL(base class library基類庫),是.NET框架的一個大類庫
C#編寫的代碼靠.NET Framework運行,結論:1.c#的體系結構和方法反映了.net基礎方法論 ?2.多數情況下,c#特定語言功能取決于.NET的功能,或依賴于.NET基類。
2. 中間語言
2.1 特征
1. 面向對象和使用接口:帶有類的單一繼承性,
2. 不同的值類型和引用類型:值類型變量之間存儲數據,引用類型變量僅存儲地址,對應的數據在該地址中找
3. 強數據類型化
4. 使用異常來處理錯誤
5. 使用特性(attribute)
3.垃圾回收
- 內存泄漏:請求內存的代碼必須顯式通知系統它什么時候不再需要該內存,很容易被遺漏,從而導致內存泄漏;
- .NET垃圾回收期是一個程序,用來清理內存。所有動態請求的內存都分配到堆上,隔一段時間.NET檢測到給定進程的托管堆已滿,需要清理時,就調用垃圾回收器。垃圾回收器處理目前代碼
? 中所有變量,檢查對存儲在托管堆上的對象的引用,沒有引用的對象被刪除。因此:不能保證什么時候會調用垃圾回收器:CLR決定需要它時就可以調用它
4. 應用程序域
- 減少運行應用程序的系統開銷,同時需要與其他程序分離開來,但仍需要彼此通信。
- windows通過地址空間把進程分隔開來,每個進程有4GB的虛擬內存來存儲其數據和可執行代碼(4GB對應32位系統),每個進程都會有不同的映射,虛擬地址空間塊映射的物理內存之間不重疊。
- 任何進程都只能通過制定虛擬內存中的一個地址來訪問內存,即進程不能直接訪問物理內存。
- 虛擬路徑:相對路徑, 物理路徑:硬盤的絕對路徑
5. 程序集
- 程序集assembly是包含編譯好的、面向.NET Framework的代碼的邏輯單元,可以存儲在多個文件中(動態程序集存儲在內存中);如果一個assembly存儲在多個文件中,其中就會有一個包含入口點的
主文件,該文件描述了程序集中的其他文件。
- 可執行代碼和庫代碼使用相同的程序集結果。但是可執行的程序集包含一個主程序的入口點;而庫程序集不包含。
- 程序集的重要特征:包含的元數據描述了兌銀代碼中定義的類型和方法,程序集也包含描述程序集本身的元數據。
?
回到頂部/編輯
* C#概述
- 塊:{語句1 ; ?語句2;} 注意:{}后面沒有分號
- Console.Write(" "); ?
*?Console.WriteLine(" Two sample integers are {0} and {1} .", 3, 6); ?從0開始替代標記、替代值
* Console.WriteLine("Three integers are {1} , {0}, {1}", 3, 6); 輸出6, 3, 6 。注意標記位和標記值一一對應,標記位從0開始。
- 格式化字符串:
* Console.WriteLine(" The value: {0:C}.", 500); ? 格式化為貨幣,$500.00
* Console.WriteLine(" {0, 10} ", 500); 正數右對齊,左邊補...
- 注釋:
*?單行//, 多行 /**/, 文檔注釋 ///
1.數據類型
?- 預定義類型16種:
- 自定義類型6種:
類(class)、結構(struct)、數組(array)、枚舉(enum)、接口(interface)
2. 棧和堆:
*?棧:是一個內存數組(桶,LIFO先進后出,后進先出)
? ? # 存儲類型:某些類型變量的值、程序當前的執行環境、傳遞給方法的參數
# 棧的特征:只能從棧頂插入(push入棧),刪除(pop出棧)
?* 堆:是一塊內存區域,可以分配大塊的內存用來存儲某類型的數據對象,可以隨意插入和移除;當對象不再被使用時,CLR的GC會自動回收
?- 值類型和引用類型
* 值類型:需要一段單獨的內存,存儲實際的數據,放在棧中
* 引用類型:需要兩段內存。第一段存儲實際的數據,放在堆中;第二段是一個引用,指向數據在堆中的存放的位置,放在棧中
* 總結:
簡單情形:值類型數據放在棧中;引用類型,實際數據始終放在堆中,引用放在棧中
復雜情形:引用類型的數據始終放在堆中;值類型對象或引用類型的引用部分可以放在堆中,也可以放在棧中,依賴于實際環境。
在賦值的時候,值類型是復制一份,新的和舊的在以后的操作中互不影響,而引用類型復制的只是地址,在以后的修改中,修改新的舊的也會受到影響。
* 為數據分配內存:
ClassA ?a = new ClassA(); ?a只是用來保存引用分配在棧中,使用new才是給實際數據分配內存【new運算符為任意指定類型的實例分配內存并初始化內存】
?
3.?變量常量
| 變量類型 | 用途 | 存儲位置 | 自動初始化 |
| 本地變量 | 在方法的作用域保存臨時數據,不是類型成員 | 棧或堆和棧 | 否 |
| 字段 | 保存和類型或類型實例相關的數據,是類型成員? | 堆 | 是 |
| 參數 | 從一個方法到另一個方法傳遞數據的臨時變量,不是類型的成員 | 棧 | 否 |
| 數組元素 | 同類數據項構成的有序集合的一個成員,可以為本地變量,也可以類型的成員 | 堆 | 類成員是,本地變量否 |
* 靜態類型:變量的類型在編譯的時候確定并且不能再運行時修改。
* dynamic:在編譯時對dynamic類型的所有信息打包,在運行時,對這些信息進行檢查,會拋出異常。
- var關鍵字(從等號右邊推斷出的實際類型的速記,并不改變C#的強類型性質)
* 只能用于本地變量,不能用于字段。
* 只能在變量聲明中包含初始化時使用(即var n = 10;)
* 一旦編譯器推斷出變量的類型,它就是固定且不能更改。
- 常量: const double PI = 3.1415; 聲明時初始化,在編譯時確定類型,不能再賦值
- DateTime dt = DateTime.Now;
- ?委托
namespace EventTest {/// <summary>/// 委托總結:委托是一種類型,和類是平級,因此不存在重載一說/// 系統提供的委托: /// 無返回值:Action無參數無返回值,Action<string, int>有參數無返回值/// 有返回值:Func<int, int>最后一個都是返回值public class SmarizeDelegate{public void Test(){MyDel del = (x, y) => { return x + y; }; //lamda表達式del(10, 20);MyDel2<int> del2 = (x, y) => x + y; //lamada表達式帶return就要帶{},不帶return就可以不帶{}del(10, 20);M1((x, y) => (x + y).ToString()); //Func有返回值委托,傳入兩個int,返回一個stringFunc<string, string, string> fn = M2(); //調用委托作為返回值的fn("你好", "徐攀");}static void M1(Func<int, int, string> fn) //委托作為方法參數類型{Console.WriteLine(fn(10, 20));}static Func<string, string, string> M2() //委托作為方法返回值{return new Func<string, string, string>((x,y) => x+y);}}public delegate int MyDel(int x, int y); //基本委托public delegate T MyDel2<T>(T t1, T t2); //泛型委托 }from:?https://www.cnblogs.com/SmileSunday/p/8434469.html
總結
- 上一篇: 七大排序算法的个人总结(三)
- 下一篇: C#里partial关键字的作用