.NET基礎知識點 l .Net平臺 .Net FrameWork框架 l .Net FrameWork框架提供了一個穩定的運行環境,;來保障我們.Net平臺正常的運轉 l 兩種交互模式 C/S:要求客戶的電腦上必須要安裝一個客戶端:qq、360、快播等..... B/S:要求客戶的電腦上只需要安裝 ...
.NET基礎知識點
l .Net平臺 .Net FrameWork框架
l .Net FrameWork框架提供了一個穩定的運行環境,;來保障我們.Net平臺正常的運轉
l 兩種交互模式
- C/S:要求客戶的電腦上必須要安裝一個客戶端:qq、360、快播等.....
- B/S:要求客戶的電腦上只需要安裝一個瀏覽器
l 書寫代碼需要註意的地方:
n 代碼中出現的所有標點都是英文半形 shift鍵快速切換中文半形和英文半形
n shift+空格切換全形/半形
n 在c#代碼中,每行代碼的結束,我們都以分號結束,註意:這個分號也是英文半形的分號。
n Console.WriteLine("要列印的內容");
n Console.ReadKey(); 暫停當前程式,等待用戶按下任意鍵繼續,按下的任意鍵將顯示在我們的控制台當中
l 註釋符:
n 1)、註銷
n 2)、解釋
l C#的3種註釋符:
n 1)、單行註釋 //
n 2)、多行註釋 /*要註釋的內容*/
n 3)、文檔註釋 /// 多用來解釋類或者方法
l 常量
n 聲明的常量的語法:
n const 變數類型變數名=值;
l 變數:用來在電腦當中存儲數據:
n 變數類型int double string char bool decimal
n 聲明並且給變數賦值的簡寫形式:
u 變數類型變數名=值;
n 變數的使用規則:
u 如果你要是用變數的話,應該要先聲明再賦值再使用。
n 給變數起名字的時候要滿足兩個命名規範:
u 1、Camel 駱駝命名規範。要求變數名首單詞的首字母要小寫,其餘每個單詞的首字母要大寫。
u 多用於給變數命名。
u 2、Pascal 命名規範:要求每個單詞的首字母都要大寫,其餘字母小寫。多用於給類或者方法命名。
u HighSchoolStudent
u highSchoolStudent
n 變數的作用域:
u 變數的作用域就是你能夠使用到這個變數的範圍。
u 變數的作用域一般從聲明它的那個括弧開始到那個括弧所對應的結束的括弧結束。
u 在這個範圍內,我們可以訪問並使用變數。超出這個範圍就訪問不到了
l 數據類型:
n 1)、整數類型:int 只能存儲整數,不能存儲小數。
n 2)、小數類型:double 既能存儲整數,也能存儲小數,小數點後面的位數 15~16位。
n 3)、金錢類型:decimal:用來村粗金錢,值後面需要加上一個m.
n 4)、字元串類型:string,用來存儲多個文本,也可以存儲空,字元串類型的值需要被雙引號引來,
n 這個雙引號必須是英文半形狀態下的雙引號
n 5)、字元類型:char,用來存儲單個字元,最多、最少只能有一個字元,不能存儲空。
n 字元類型的值需要用單引號因起來。英文半形狀態下的單引號。
l 波浪線
n 1)、如果你的代碼中出現了紅色的波浪線,意味著你的代碼中出現了語法錯誤。
n 2)、如果你的代碼中出現了綠色的波浪線,說明你的代碼語法並沒有錯誤,
n 只不過提示你有可能會出現錯誤,但是不一定會出現錯誤。警告
l 命名規則:
n ****首先要保證的就是這個變數的名字要有意義。
n 1 現階段給變數起名字的時候都以字母開頭
n 2 後面可以跟任意“字母”、數字、下劃線.
n 註意:
u 1)你起的變數名不要與c#系統中的關鍵字重覆.
u 2)在c#中,大小寫是敏感的. HTML
u 3)同一個變數名不允許重覆定義(先這麼認為,不嚴謹)
l 賦值運算符
n =:表示賦值的意思,表示把等號右邊的值,賦值給等號左邊的變數。
n 由等號連接的表達式稱之為賦值表達式。
n 註意:每個表達式我們都可以求解除一個定值,對於賦值表達式而言,等號左邊的變數的值,
n 就是整個賦值表達式的值。
n int number=10;
l +號的作用
n 1)、連接:當+號兩邊有一邊是字元串的時候,+號就起到連接的作用。
n 2)、相加:兩邊是數字的時候
l 占位符
n 使用方法:先挖個坑,再填個坑。
n 使用占位符需要註意的地方:
n 1、你挖了幾個坑,就應該填幾個坑,如果你多填了,沒效果。
n 如果你少填了,拋異常。
n 2、輸出順序:按照挖坑的順序輸出。
l 異常
n 異常是指:語法上並沒有任何錯誤,只不過在程式運行的期間,由於某些原因出現了問題,
n 使程式不能再正常的運行。
l 轉義符
n 轉義符指的就是一個'\'+一個特殊的字元,組成了一個具有特殊意義的字元。
n \n:表示換行
n \":表示一個英文半形的雙引號
n \t:表示一個tab鍵的空格
n \b:表示一個退格鍵,放到字元串的兩邊沒有效果。
n \r\n:windows操作系統不認識\n,只認識\r\n
n \\:表示一個\
n
n @符號
n 1、取消\在字元串中的轉義作用,使其單純的表示為一個'\'
n 2、將字元串按照編輯的原格式輸出
l 算數運算符
n +
n -
n *
n /
n %
l 類型轉換
n 隱式類型轉換:
n 我們要求等號兩遍參與運算的操作數的類型必須一致,如果不一致,滿足下列條件會發生
u 自動類型轉換,或者稱之為隱式類型轉換。
u 兩種類型相容
u 例如:int 和 double 相容(都是數字類型)
u 目標類型大於源類型
u 例如:double > int 小的轉大的
n 顯示類型轉換:
u 1、兩種類型相相容 int--double
u 2、大的轉成小的 double----int
n 語法:
u (待轉換的類型)要轉換的值;
n
n 總結:
u 自動類型轉換:int---->doublec 小的轉大的
u 顯示類型轉換:double--->int 大的轉小的
l Convert進行類型轉換:
n 類型如果相相容的兩個變數,可以使用自動類型轉換或者強制類型轉換,但是,如果兩個類型的變數不相容,比如 string與int或者string 與double,這個時候我們可以使用一個叫做Convert的轉換工廠進行轉換。
n 註意:使用Convert進行類型轉換,也需要滿足一個條件:
u 面兒上必須要過的去。
l 算數運算符
n ++:分為前++和後++,不管是前++還是後++,最終的結果都是給這個變數加一。
n 區別表現表達式當中,如果是前++,則先給這個變數自身加一,然後帶著這個加一後的值去參與運算。
n 如果是後++,則先拿原值參與運算,運算完成後,再講這個變數自身加一。
n --:同上。
l 對於向加加或者減減這樣只需要一個操作數就能完成的運算,我們稱之為一元運算符。
l + - * / % 對於這些需要兩個或以上才能完成運算的操作符,我們稱之為二元運算符。
l 一元運算符的優先順序要高於而元運算符。
l 如果在一個表達式當中,既有一元運算符,又有二元運算符,我們首先計算一元運算符。
l
l int number=10;
l int result=10 + ++number;
l 關係運算符
n >
n <
n >=
n <=
n ==
n !=
n 關係運算符是用來描述兩個事物之間的關係
n 由關係運算符連接的表達式稱之為關係表達式。
l bool類型
n 在c#中我們用bool類型來描述對或者錯。
n bool類型的值只有兩個一個true 一個false
l 邏輯運算符
n && 邏輯與
n ||邏輯或
n !邏輯非
n 又邏輯運算符連接的表達式叫做邏輯表達式
n 邏輯運算符兩邊放的一般都是關係表達式或者bool類型的值。
n 5>3 &&true
n 3>5||false
n !表達式
n 邏輯表達式的結果同樣也是bool類型
l 複合賦值運算符
n int number=10;
n += :
n number+=20;
n number=number+20;
n -=
n number-=5;
n number=number-5;
n *=
n number*=5;
n number=number*5;
n /=
n %=
l 三元表達式
n 語法:
u 表達式1?表達式2:表達式3;
n 表達式1一般為一個關係表達式。
n 如果表達式1的值為true,那麼表達式2的值就是整個三元表達式的值。
n 如果表達式1的值為false,那麼表達式3的值就是整個三元表達式的值。
n 註意:表達式2的結果類型必須跟表達式3的結果類型一致,並且也要跟整個三元表達式的結果類型一致。
l if語句:
n 語法:
u if(判斷條件)
u {
u 要執行的代碼;
u }
n 判斷條件:一般為關係表達式或者bool類型的值。
n 執行過程:
u 程式運行到if處,首先判斷if所帶的小括弧中的判斷條件,
u 如果條件成立,也就是返回true,則執行if所帶的大括弧中的代碼,
u 如果判斷條件不成立,也就是返回一個false。則跳過if結構,繼續向下執行。
n
n if結構的特點:先判斷,再執行,有可能一行代碼都不執行
n 用於一種情況的判斷。
l if-else
n 語法:
u if(判斷條件)
u {
u 執行的代碼;
u }
u else
u {
u 執行的代碼
u }
n 執行過程:
u 程式執行到if處,首先判斷if所帶的小括弧中的判斷條件是否成立,
u 如果成立,也就是返回一個true,則執行if所帶的大括弧中的代碼,
u 執行完成後,跳出if-else結構。
u 如果if所帶的小括弧中的判斷條件不成立,也就是返回一個false,
u 則跳過if語句,執行else所帶的大括弧中的語句,執行完成後,跳出if-else結構。
n
n if-else特點:先判斷,再執行,最少都要執行一條代碼。
n 用於兩種情況的判斷
n 註意:else永遠跟離它最近的那個if配對
l if else-if
n 作用:用來處理多條件的區間性的判斷。
n 語法:
u if(判斷條件)
u {
u 要執行的代碼;
u }
u else if(判斷條件)
u {
u 要執行的代碼;
u }
u else if(判斷條件)
u {
u 要執行的代碼;
u }
u else if(判斷條件)
u {
u 要執行的代碼;
u }
u ........
u else
u {
u 要執行的代碼;
u }
n 執行過程;
u 程式首先判斷第一個if所帶的小括弧中的判斷條件,如果條件成立,也就是返回一個true,
u 則執行該if所帶的大括弧中的代碼,執行完成後,立即跳出if else-if結構。
u 如果第一個if所帶的判斷條件不成立,也就是返回一個false,則繼續向下進行判斷,依次的判斷每一個if所帶
u 的判斷條件,如果成立,就執行該if所帶的大括弧中的代碼,如果不成立,則繼續向下判斷,
u 如果每個if所帶的判斷條件都不成立,就看當前這個if else-if結構中是否存在else。
u 如果有else的話,則執行else中所帶的代碼,如果沒有else,則整個 if-else if神馬都不做。
u else可以省略。
l 異常捕獲
n 我們在程式中經常會出現各種各樣的異常,你如果想要你的程式變得堅強一些。
n 在你的代碼中應該經常性的使用try-catch來進行異常捕獲。
n
n 哪行代碼有可能出現異常,你就踹它一腳。
n 語法:
u try
u {
u 可能會出現異常的代碼;
u ....
u ...
u ...
u }
u //try和catch之間不能有其他的代碼
u catch
u {
u 出現異常後要執行的代碼;
u }
n
n 執行過程:如果try中的代碼沒有出現異常,那麼catch中的代碼不會執行。
n 如果try中的代碼出現了異常,那怕這行出現異常的代碼後面還有一百行都不會執行了,
n 而是直接跳到catch中執行代碼
l switch-case
n 用來處理多條件的定值的判斷。
n 語法:
u switch(變數或者表達式的值)
u {
u case 值1:要執行的代碼;
u break;
u case 值2:要執行的代碼;
u break;
u case 值3:要執行的代碼;
u break;
u ..........
u default:要執行的代碼;
u break;
u }
n 執行過程:
u 程式執行到switch處,首先將括弧中變數或者表達式的值計算出來,
u 然後拿著這個值依次跟每個case後面所帶的值進行匹配,一旦匹配成功,則執行
u 該case所帶的代碼,執行完成後,遇到break。跳出switch-case結構。
u 如果,跟每個case所帶的值都不匹配。就看當前這個switch-case結構中是否存在
u default,如果有default,則執行default中的語句,如果沒有default,則該switch-case結構什麼都不做。
l 迴圈結構
n while迴圈:
u while(迴圈條件)
u {
u 迴圈體;
u }
n 執行過程:
u 程式運行到while處,首先判斷while所帶的小括弧內的迴圈條件是否成立,
u 如果成立的話,也就是返回一個true,則執行迴圈體,執行完一遍迴圈體後,再次回到
u 迴圈條件進行判斷,如果依然成立,則繼續執行迴圈體,如果不成立,則跳出while迴圈。
u 在while迴圈當中,一般總會有那麼一行代碼,能夠改變迴圈條件,使之終有一天不再成立,
u 如果沒有那麼一行代碼能夠改變迴圈條件,也就是迴圈條件永遠都成立,我們稱之這種迴圈叫做死迴圈。
u 最簡單的最常用的死迴圈:
l while(true)
l {
l
l }
n 特點:先判斷,再執行,有可能一遍迴圈都不執行。
l do-while迴圈。
n 語法:
u do
u {
u 迴圈體;
u }while(迴圈條件);
n 執行過程:程式首先會執行do中的迴圈體,執行完成後,去判斷do-while迴圈的迴圈條件,
n 如果成立,則繼續執行do中的迴圈體,如果不成立,則跳出do-while迴圈。
n 特點:先迴圈,再判斷,最少執行一遍迴圈體。
l for迴圈
n 語法:
u for(表達式1;表達式2;表達式3)
u {
u 迴圈體;
u }
n 表達式1一般為聲明迴圈變數,記錄迴圈的次數(int i=0;)
n 表達式2一般為迴圈條件(i<10)
n 表達式3一般為改變迴圈條件的代碼,使迴圈條件終有一天不再成立(i++)。
n 執行過程:
u 程式首先執行表達式1,聲明瞭一個迴圈變數用來記錄迴圈的次數,
u 然後執行表達式2,判斷迴圈條件是否成立,如果表達式2返回的結果為true,
u 則執行迴圈體。當執行完迴圈體後,執行表達式3,然後執行表達式2繼續判斷迴圈條件是否成立,
u 如果成立則繼續執行迴圈體,如果不成立,則跳出for迴圈。
l break
n 1)、可以跳出switch-case結構。
n 2)、可以跳出當前迴圈。
n break一般不單獨的使用,而是跟著if判斷一起使用,表示,當滿足某些條件的時候,就不再迴圈了。
l 程式調試
n 1)、寫完一段程式後,想看一下這段程式的執行過程。
n 2)、當你寫完這段程式後,發現,程式並沒有按照你想象的樣子去執行。
n
n 調試方法:
u 1)、F11逐語句調試(單步調試)
u 2)、F10逐過程調試
u 3)、斷點調試
l int.TryParse int.parse 嘗試著將一個字元串轉換成int類型。
l 枚舉
n 語法:
u 訪問修飾符enum 枚舉名
u {
u 值1,
u 值2,
u 值3,
u ........
u }
n enum:關鍵字,聲明枚舉的關鍵字
n 枚舉名:要符合Pascal命名規範
n
n 將枚舉聲明到命名空間的下麵,類的外面,表示這個命名空間下,所有的類都可以使用這個枚舉。
n
n 枚舉就是一個變數類型,int--double string decimal.
n 只是枚舉聲明、賦值、使用的方式跟那些普通的變數類型不一樣。
n 我們可以將一個枚舉類型的變數跟int類型和string類型互相轉換。
n 枚舉類型預設是跟int類型相互相容的,所以可以通過強制類型轉換的語法互相轉換。
n 當轉換一個枚舉中沒有的值的時候,不會拋異常,而是直接將數字顯示出來。
n 枚舉同樣也可以跟string類型互相轉換,如果將枚舉類型轉換成string類型,則直接調用ToString().
n 如果將字元串轉換成枚舉類型則需要下麵這樣一行代碼:
n (要轉換的枚舉類型)Enum.Parse(typeof(要轉換的枚舉類型),"要轉換的字元串");
n 如果轉換的字元串是數字,則就算枚舉中沒有,也會不會拋異常。
n 如果轉換的字元串是文本,如果枚舉中沒有,則會拋出異常。
l 結構
n 可以幫助我們一次性聲明多個不同類型的變數。
n 語法:
u [public] struct 結構名
u {
u 成員;//欄位
u }
n 變數在程式運行期間只能存儲一個值,而欄位可以存儲多個值。
l 數組
n 一次性存儲多個相同類型的變數。
n 語法:
n 數組類型[] 數組名=new 數組類型[數組長度];
n
n ***數組的長度一旦固定了,就不能再被改變了
l 冒泡排序:就是將一個數組中的元素按照從大到小或者從小到大的順序進行排列。
n int[] nums={9,8,7,6,5,4,3,2,1,0}; 0 1 2 3 4 5 6 7 8 9
n 第一趟比較:8 7 6 5 4 3 2 1 0 9 交換了9次 i=0j=nums.Length-1-i
n 第二趟比較:7 6 5 4 3 2 1 0 8 9 交換了8次 i=1j=nums.Length-1-i
n 第三趟比較:6 5 4 3 2 1 0 7 8 9 交換了7次 i=2j=nums.Length-1-i
n 第四趟比較:5 4 3 2 1 0 6 7 8 9 交換了6次 i=3j=nums.Length-1-i
n 第五趟比較:4 3 2 1 0 5 6 7 8 9 交換了5次
n 第六趟比較:3 2 1 0 4 5 6 7 8 9 交換了4次
n 第七趟比較:2 1 0 3 4 5 6 7 8 9 交換了3次
n 第八趟比較:1 0 2 3 4 5 6 7 8 9 交換了2次
n 第九趟比較:0 1 2 3 4 5 6 7 8 9 交換了1次
n for(int i=0;i<number.Length-1;i++)
n {
n for(int j=0;j<nums.Length-1-i;j++)
n {
n if(nums[j]>nums[j+1])
n {
n int temp=nums[j];
n nums[j]=nums[j+1];
n nums[j+1]=temp;
n }
n }
n }
l 方法
n 函數就是將一堆代碼進行重用的一種機制。
n 函數的語法:
u [public] static 返回值類型方法名([參數列表])
u {
u 方法體;
u }
u public:訪問修飾符,公開的,公共的,哪都可以訪問。
u static:靜態的
u 返回值類型:如果不需要寫返回值,寫void
u 方法名:Pascal 每個單詞的首字母都大些。其餘字母小寫
u 參數列表:完成這個方法所必須要提供給這個方法的條件。如果沒有參數,小括弧也不能省略。
u
u 方法寫好後,如果想要被執行,必須要在Main()函數中調用。
u 方法的調用語法:
u 類名.方法名([參數]);
u ***在某些情況下,類名是可以省略的,如果你寫的方法跟Main()函數同在一個類中,這個時候,
u 類名可以省略。
n 方法的功能一定要單一。
u GetMax(int n1,int n2)
u 方法中最忌諱的就是出現提示用戶輸入的字眼。
l return
n 1、在方法中返回要返回的值。
n 2、立即結束本次方法。
l 我們在Main()函數中,調用Test()函數,
n 我們管Main()函數稱之為調用者,
n 管Test()函數稱之為被調用者。
n 如果被調用者想要得到調用者的值:
u 1)、傳遞參數。
u 2)、使用靜態欄位來模擬全局變數。
n 如果調用者想要得到被調用者的值:
u 1)、返回值
l 不管是實參還是形參,都是在記憶體中開闢了空間的。
l out、ref、params
n 1)、out參數。
u 如果你在一個方法中,返回多個相同類型的值的時候,可以考慮返回一個數組。
u 但是,如果返回多個不同類型的值的時候,返回數組就不行了,那麼這個時候,
u 我們可以考慮使用out參數。
u out參數就側重於在一個方法中可以返回多個不同類型的值。
n
n 2)、ref參數
u 能夠將一個變數帶入一個方法中進行改變,改變完成後,再講改變後的值帶出方法。
u ref參數要求在方法外必須為其賦值,而方法內可以不賦值。
n
n 3)、params可變參數
u 將實參列表中跟可變參數數組類型一致的元素都當做數組的元素去處理。
u params可變參數必須是形參列表中的最後一個元素。
l 方法的重載
n 概念:方法的重載指的就是方法的名稱相同給,但是參數不同。
n 參數不同,分為兩種情況
u 1)、如果參數的個數相同,那麼參數的類型就不能相同。
u 2)、如果參數的類型相同,那麼參數的個數就不能相同。
u ***方法的重載跟返回值沒有關係。
l 方法的遞歸
n 方法自己調用自己。
n 找出一個文件夾中所有的文件。
l 面向過程-----> 面向對象
l
l 面向過程:面向的是完成這件事兒的過程,強調的是完成這件事兒的動作。
l 類
n 語法:
u [public] class 類名
u {
u 欄位;
u 屬性;
u 方法;
u }
n 寫好了一個類之後,我們需要創建這個類的對象,
n 那麼,我們管創建這個類的對象過程稱之為類的實例化。
n 使用關鍵字 new.
n
n this:表示當前這個類的對象。
n 類是不占記憶體的,而對象是占記憶體的。
l 屬性
n 屬性的作用就是保護欄位、對欄位的賦值和取值進行限定。
n 屬性的本質就是兩個方法,一個叫get()一個叫set()。
n 既有get()也有set()我們誠之為可讀可寫屬性。
n 只有get()沒有set()我們稱之為只讀屬性
n 沒有get()只有set()我們稱之為只寫屬性
n
n Field欄位
n Method方法
n Property屬性
n
n ****欄位就是女人 屬性才是男人。
l 訪問修飾符:
訪問修飾符 |
說明 |
public |
公有訪問。不受任何限制。 |
private |
私有訪問。只限於本類成員訪問,子類,實例都不能訪問。 |
protected |
保護訪問。只限於本類和子類訪問,實例不能訪問。 |
internal |
內部訪問。只限於本項目內訪問,其他不能訪問。 |
protected internal |
內部保護訪問。只限於本項目或是子類訪問,其他不能訪問 |
l 當我們創建好一個類的對象後,需要給這個對象的每個屬性去賦值。我們管這個過程稱之為對象的初始化。
l 靜態和非靜態的區別
n 1)、在非靜態類中,既可以有實例成員,也可以有靜態成員。
n 2)、在調用實例成員的時候,需要使用對象名.實例成員;
n 在調用靜態成員的時候,需要使用類名.靜態成員名;
n 總結:靜態成員必須使用類名去調用,而實例成員使用對象名調用。
n 靜態函數中,只能訪問靜態成員,不允許訪問實例成員。
n 實例函數中,既可以使用靜態成員,也可以使用實例成員。
n 靜態類中只允許有靜態成員,不允許出現實例成員。
n
n 使用:
n 1)、如果你想要你的類當做一個"工具類"去使用,這個時候可以考慮將類寫成靜態的。
n 2)、靜態類在整個項目中資源共用。
n 只有在程式全部結束之後,靜態類才會釋放資源。
l
l
l 堆 棧 靜態存儲區域
l
l 釋放資源。GC Garbage Collection垃圾回收器
l 構造函數
n 作用:幫助我們初始化對象(給對象的每個屬性依次的賦值)
n 構造函數是一個特殊的方法:
u 1)、構造函數沒有返回值,連void也不能寫。
u 2)、構造函數的名稱必須跟類名一樣。
n
n 創建對象的時候會執行構造函數
n 構造函數是可以有重載的。
n ***
n 類當中會有一個預設的無參數的構造函數,當你寫一個新的構造函數之後,不管是有參數的還是
n 無參數的,那個預設的無參數的構造函數都被幹掉了。
l new關鍵字
n Person zsPerson=new Person();
n new幫助我們做了3件事兒:
u 1)、在記憶體中開闢一塊空間
u 2)、在開闢的空間中創建對象
u 3)、調用對象的構造函數進行初始化對象
n 1)、創建對象
n 2)、隱藏從父類那裡繼承過來的同名成員。
n 隱藏的後果就是子類調用不到父類的成員。
l this關鍵字
n 1)、代表當前類的對象
n 2)、在類當中顯示的調用本類的構造函數 :this
l 命名空間
n 可以認為類是屬於命名空間的。
n 如果在當前項目中沒有這個類的命名空間,需要我們手動的導入這個類所在的
n 命名空間。
u 1)、用滑鼠去點
u 2)、alt+shift+F10
u 3)、記住命名空間,手動的去引用
l 值類型和引用類型
l 區別:
u 1、值類型和引用類型在記憶體上存儲的地方不一樣。
u 2、在傳遞值類型和傳遞引用類型的時候,傳遞的方式不一樣。
u 值類型我們稱之為值傳遞,引用類型我們稱之為引用傳遞。
n 我們學的值類型和引用類型:
u 值類型:int、double、bool、char、decimal、struct、enum
u 引用類型:string、自定義類、數組
n 存儲:
u 值類型的值是存儲在記憶體的棧當中。
u 引用類型的值是存儲在記憶體的堆中。
n 值類型在複製的時候,傳遞的是這個值得本身。
n 引用類型在複製的時候,傳遞的是對這個對象的引用。
l 字元串
n 1)、字元串的不可變性
n 當你給一個字元串重新賦值之後,老值並沒有銷毀,而是重新開闢一塊空間存儲新值。
n 當程式結束後,GC掃描整個記憶體,如果發現有的空間沒有被指向,則立即把它銷毀。
n 2)、我們可以講字元串看做是char類型的一個只讀數組。
n ToCharArray();將字元串轉換為char數組
n new string(char[] chs):能夠將char數組轉換為字元串
l 字元串提