【C#高級編程】忽略基礎知識點梳理


     忽略基礎知識點梳理

概述:今天打開一本《C#高級編程》值類型與引用類型翻看,發現有些熟悉的知識點跟以往認識很不一樣,今天對某些忽略點的在認識做一些總結。以便深刻理解,倘若你也遇到過,以此共享!。

C#基礎系列導航


  1. C#實現隊列讀寫操作(一)
  2. 變化多端的列表(二)
  3. VS自動內存管理(垃圾回收集)(三)
  4. C#忽略基礎知識點梳理(四)
  5. 什么是框架的接口(五)
  6. 程序集的加載與反射(六)
  7. CLR寄宿和應用程序域(七)
  8. 異常(八)

  預定義數據類型:

      這個里面有個重心點也是很多面試點就是值類型與引用類型。本人已多次總結,這里不再過多解釋。那么我想關心什么是預定義類型?預定義類型多么?有多少呢?

       預定義類型是具有CTS標准規范的類型,他們並不內置在C#中,而是內置的.NET Framework中。其他類型都來源於預定義類型的繼承。C#預定義類型一共有15個,其中值類型13個(sbyte,short,int,long,byte,ushort,uint,ulong)2個浮點類型(float,dpuble)和1個decimal型,1個bool型,1個字符型(char)和2個預定義引用類型(object,string),object父類毋庸置疑,但是string的引用類型就顯得比較特殊了。

String引用類型有何特殊?

        static void Main(string[] args) { string s1 = "hello Tom!"; string s2 = s1; Console.WriteLine(s1); Console.WriteLine(s2); Console.Read(); }

輸出結果1:

修改s1數據:

        static void Main(string[] args) { string s1 = "hello Tom!"; string s2 = s1; s1 = "New hello Tom!"; Console.WriteLine(s1); Console.WriteLine(s2); Console.Read(); }

運行結果2:

很明顯結果是不一致的。原因在於:

結果1:s1引用類型分配在堆中。s2對象指向s1地址索引這個沒問題!相信大家都能理解,這個不在詳細描述,隨后咱們反匯編一下!

結果2:s1原先在堆分配內存中分配地址1(hello Tom!),現在對s1對象重新賦值。相當於new s1.那么堆自然會給s1分配新內存地址2(new hello Tom!).然而s2依舊指向地址1(hello Tom!)中.運行后自然結果不同。

 

      為了詳細剖析咱們想想。根據結果不同,肯定s2的內存分配大小更大,而且在調用時s1和s2在第一次調用同一個地址,第二次肯定不同。我們的猜想對於不對?需要實際驗證,調用兩者反匯編代碼:

IL1:

IL2:結果2地內存大小偏大,我們猜想一正確。IL_0009是加載新的string,我們驗證沒錯。

下面了解下有關編譯C#文件更多內容

      C#代碼是托管代碼我們所知道的。其原理就是c#代碼經過相應的C#編譯器(CSC.exe)編譯的IL語言。這一點與C,C++,JAVA都是一樣的,它們也同樣對應相應編譯器編譯到IL。這里主要介紹C#編譯器。其編譯選項主要有哪些呢?

1./t:exe        輸出控制台應用程序。

2,/t:library    輸出帶有清單(Il和元數據等)類庫

3,/t:modult    輸出沒有清單的組件

4,/t:winexe    輸出windows應用程序(么有控制台窗口)

具體使用:咱們以類庫Librayry.cs文件為例。其經過生成后為Librayry.dll。命令編譯為:csc /t:library Librayry.cs(同vs中生成一樣效果)

控制台I/O問題,也許還有你所不知道的?

1,一個算法輸出如下格式:1,空格會顯示輸出,{m,n}m是表示第m個索引一般0到m,n是寬度值

            int i=330; int j = 30; Console.WriteLine(" {0,4}\n+{1,4}\n-----\n {2,4}", i, j, i + j); Console.ReadKey();

2,帶有美元符號控制格式輸出

            decimal i=345.34m; decimal j = 76.7m; Console.WriteLine(" {0,9:C2}\n+{1,9:C2}\n-----------\n {2,9:C2}", i, j, i + j); Console.ReadKey();

3,也可以占位符表示:

            double d = 0.544; Console.WriteLine(" {0:#.00}", d); Console.ReadKey();

下面就介紹下C#預處理器指令吧!

      熟悉c與C++開發的預定義指令一定也不陌生,但是我開始學習C#時以為C#沒有預定義概念,應該平常就不會用到它。其實這也正是其作為托管代碼的原因所在,C#同樣具有與預處理指令。就像內存分配一樣,C#不需要手動分配,托管堆會自動分配(上面string分析中結果1的30個大小內存就是自動分配,記得吧?)預處理指令很好認,開頭都是#

1,#define和#undef

這里的#define不是實際代碼的一部分,只是告訴編譯器它定義對象的存在。只在編譯代碼時存在

#undef,顯而易見,這個就相當於刪除定義啦

2,#if,#elif(else if),#else ,#endif

這里同樣是成對存在的,使用方法與平常if語句一樣,但是注意這里;代碼演示吧!

這是粘貼出來的,原始定義debug,這里不存在,所有代碼編譯不會通過,代碼部分為灰色。

 我強制拿一句Console.ReadKey();運行結果是空白:

3,#warning和#error

這個大家肯定非常熟悉,我們編譯出錯警告都會遇到,究竟怎么出現呢?原理是什么?

當編譯器遇到它們兩個會產生警告和錯誤。如果編譯器遇到#warning時候,會顯示其指令后面的代碼,這個過程也是C#對應編譯器實現的。然后繼續往下運行。但是如果遇到#error會顯示錯誤信息,立即退出編譯,並且不會產生IL代碼。即便查看也是沒有的

4#region和#endregion

  #region   預編譯#If應用
#if debug
            double d = 0.544; Console.WriteLine(" {0:#.00}", d); Console.ReadKey(); #endif Console.ReadKey(); #endregion

點擊節點

這個過程中編譯器識別這對指令,可以讓代碼塊折疊,更好代碼布局和顯示。這個過程中它們好像沒有什么用,不影響編譯過程。

C#編程規則異常重要!

C#規范編程,這樣對於自己也是好的風格,思路清晰,讓別人看起來也清晰明了。特別團隊合作和別人維護都很重要!(個人總結幾點)

1,命名空間異常重要,有時候可能在你都計算機可以,移植到另一台就命名沖突。故采用公司名/個人名.項目名稱:如zhangsan.demo

2,私有變量頭字母小寫:如myTd

3,公用的或者保護類型:如MyId

4,必須字母或者下划線開頭,可以追加數字:_myId

5,不能包含關鍵字,但是加@可以:如@int

6屬性和方法盡可能讓人能夠一看即懂:如:SetPassword()

 


 

       到此,今天所看到的的細節問題基本總結完了。明天由於還要早起,暫時到這吧!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM