精講(新手友好,詳盡版))
前置回顧C# 是強類型靜態(tài)語言。變量一旦聲明類型就固定。 類型轉換 將一個類型的數(shù)據(jù)變成另一個類型的數(shù)據(jù)。核心總綱隱式轉換編譯器自動幫你轉安全、不會丟數(shù)據(jù)無需寫任何轉換代碼。顯式強制轉換強制轉型你手動告訴編譯器去轉換有可能丟失數(shù)據(jù)、溢出必須寫(目標類型)。Convert 工具類轉換跨類型轉換神器尤其適合【字符串 ? 基礎類型】轉換失敗直接拋異常。TryParse 安全解析推薦生產(chǎn)代碼使用嘗試解析失敗不崩潰返回 bool 標記成功與否。裝箱 拆箱值類型 ? object 引用類型之間的特殊轉換伴隨內存操作。as 與 is 運算符引用類型安全轉換避免強制轉換拋異常。學習思路逐個學習每種轉換方式 → 看懂內存機理 → 對比適用場景 → 識別坑點 → 動手敲示例。1. 隱式類型轉換Implicit Conversion一句話定義由編譯器自動完成不需要寫任何轉換代碼只有保證不會丟失信息時編譯器才允許隱式轉換。規(guī)則小范圍類型 → 大范圍類型安全擴容。整數(shù)從小到大順序方便記憶sbyte→short→int→long→float→double為什么這個順序 把小容器的數(shù)據(jù)放進更大的容器數(shù)據(jù)完整保留不會丟失。示例 1整數(shù)隱式轉換using System; namespace ImplicitDemo { class Program { static void Main(string[] args) { int numInt 100; long numLong numInt; // ? 隱式轉換 int → long自動完成 double numDouble numInt; // ? int → double 隱式轉換 Console.WriteLine($numInt{numInt}, numLong{numLong}, numDouble{numDouble}); } } }機理拆解numInt棧內存是 int4 字節(jié)存放 100賦值給numLonglong 8 字節(jié)編譯器自動把 100 復制一份放到 8 字節(jié)空間數(shù)據(jù)完整無損long 容量比 int 大不存在溢出、丟失數(shù)據(jù)風險編譯器允許自動轉換。? 反向不允許大范圍 → 小范圍不能隱式轉換long big 99999; int small big; //編譯報錯long范圍大于int可能數(shù)據(jù)丟失編譯器禁止隱式轉換示例 2char 隱式轉 intchar 底層存儲 Unicode 編碼數(shù)字可以隱式轉為 intchar ch A; int code ch; //隱式轉換 A 的Unicode碼65存入code Console.WriteLine(code); //輸出65但是 int不能隱式轉 char因為 int 范圍太大可能超出字符編碼范圍。示例 3隱式轉換適用場景方法傳參時自動隱式轉換static void PrintDouble(double d) { Console.WriteLine(d); } static void Main(string[] args) { int a 10; PrintDouble(a); //int自動隱式轉為double }? 隱式轉換特點總結自動執(zhí)行代碼干凈無損不會截斷、丟失數(shù)據(jù)只能小范圍→大范圍編譯期檢查不通過直接報錯。2. 顯式強制轉換Explicit Cast強制轉型一句話程序員手動強制告訴編譯器執(zhí)行類型轉換。你主動承擔數(shù)據(jù)丟失、溢出風險。語法格式目標類型 變量名 (目標類型)源變量;適用場景大范圍類型 → 小范圍類型double→int 等。示例 1double 強制轉為 int小數(shù)截斷不是四舍五入新手大坑using System; namespace CastDemo { class Program { static void Main(string[] args) { double d1 3.99; int num1 (int)d1; //強制轉換 double → int Console.WriteLine(num1); //輸出3小數(shù)直接丟掉不會四舍五入 double d2 -2.99; int num2 (int)d2; Console.WriteLine(num2); //輸出 -2 } } }機理強制轉型(int)作用直接砍掉小數(shù)部分只保留整數(shù)部分不是數(shù)學上的四舍五入。如果想要四舍五入要用Math.Round()而不是強制轉型。double d 3.99; int res (int)Math.Round(d); Console.WriteLine(res); //4示例 2long 強制轉 int溢出風險long bigNum 3000000000; //超過int最大值2147483647 int smallNum (int)bigNum; Console.WriteLine(smallNum); //得到一個錯誤負數(shù)發(fā)生溢出機理long 8 字節(jié)數(shù)據(jù)強行塞進 4 字節(jié) int 空間超出部分直接截斷結果錯亂。生產(chǎn)環(huán)境需要溢出檢查可以使用checked關鍵字開啟溢出檢測溢出會拋異常。checked { long bigNum 3000000000; int smallNum (int)bigNum; //溢出運行時報錯 }示例 3int 強制轉 charint code 65; char ch (char)code; Console.WriteLine(ch); //輸出 A?? 強制轉換的局限(int)這種強制轉型不能直接把字符串轉數(shù)字string str 123; int num (int)str; //編譯報錯string和int完全不兼容不能用這種強制轉型字符串轉數(shù)字要用 Convert / Parse這是新手高頻錯誤。? 強制轉換適用場景數(shù)字類型之間互相轉換明確知道數(shù)據(jù)不會溢出。3. Convert 類轉換Convert是.NET 內置工具類提供大量靜態(tài)方法用于跨類型轉換。核心特點可以把字符串、bool、數(shù)字互相轉換轉換失敗直接拋出異常程序崩潰。常用方法Convert.ToInt32()→ 轉為 intConvert.ToDouble()→ 轉為 doubleConvert.ToDecimal()→ 轉為 decimal金額Convert.ToString()→ 任意類型轉為字符串Convert.ToBoolean()→ 轉為 bool示例 1字符串轉數(shù)字控制臺程序最常用using System; namespace ConvertDemo { class Program { static void Main(string[] args) { Console.Write(請輸入數(shù)字); string input Console.ReadLine(); int num Convert.ToInt32(input); Console.WriteLine(數(shù)字10 (num 10)); } } }機理Convert.ToInt32內部會解析傳入字符串嘗試識別數(shù)字。 ? 用戶輸入100→ 成功轉為 100 ? 用戶輸入abc→拋出 FormatException 異常程序直接崩潰。示例 2數(shù)字轉字符串int a 99; string s Convert.ToString(a); Console.WriteLine(s);示例 3Convert 處理小數(shù)轉 int和強制轉型不一樣重點對比(int)直接截斷小數(shù)Convert.ToInt32 會四舍五入double d 3.5; int r1 (int)d; //3直接截斷 int r2 Convert.ToInt32(d); //4四舍五入 Console.WriteLine($r1{r1}, r2{r2});這是非常重要的區(qū)別很多新手踩坑。? Convert 適用場景快速簡單轉換確定輸入一定合法不會出現(xiàn)錯誤格式。如果輸入來源是用戶不推薦直接用 Convert。4. Parse / TryParse字符串解析?生產(chǎn)代碼首選Parse字符串解析成對應類型失敗拋異常。TryParse安全嘗試解析失敗不崩潰返回 bool 表示是否成功。適用場景專門把字符串解析成基礎值類型int、double、decimal 等。4.1 Parse 示例string str 123; int num int.Parse(str); Console.WriteLine(num); //int num2 int.Parse(abc); //運行報錯解析失敗機理int.Parse只負責解析字符串文本為整數(shù)輸入非數(shù)字字符串直接異常。和 Convert.ToInt32 細微差別Parse只能接收字符串Convert 可以接收多種類型。4.2 TryParse重點寫項目優(yōu)先用這個語法模板bool 結果 類型.TryParse(待解析字符串, out 輸出變量);返回 booltrue 解析成功false 解析失敗out輸出參數(shù)解析成功解析結果放入變量失敗變量默認值 0。using System; namespace TryParseDemo { class Program { static void Main(string[] args) { Console.Write(請輸入年齡); string input Console.ReadLine(); int age; bool parseSuccess int.TryParse(input, out age); if (parseSuccess) { Console.WriteLine($解析成功你的年齡{age}); } else { Console.WriteLine(輸入格式錯誤不是合法數(shù)字); } } } }機理拆解用戶輸入文本存入字符串 inputint.TryParse嘗試從頭到尾解析這個字符串如果全部字符都是合法數(shù)字返回 true把解析后的數(shù)字寫入 age 變量如果有字母、符號返回 falseage 賦值默認 0不會拋出異常程序不會崩潰。TryParse 是處理用戶輸入的最佳實踐做控制臺、網(wǎng)頁、桌面程序用戶輸入數(shù)字一律優(yōu)先 TryParse。拓展double.TryParse、decimal.TryParse、bool.TryParse 用法完全一致。5. 裝箱與拆箱特殊類型轉換值類型 ? objectobject 是 C# 所有類型的根父類。任何值類型都可以轉為 object這個過程叫裝箱object 轉回原來的值類型叫拆箱。 本質跨越棧內存和堆內存的轉換有性能開銷。示例裝箱 拆箱using System; namespace BoxDemo { class Program { static void Main(string[] args) { int num 10; //棧內存值類型 object obj num; //【裝箱】 Console.WriteLine(obj); int num2 (int)obj; //【拆箱】強制轉換取出值 Console.WriteLine(num2); } } }機理非常關鍵int num 10;棧開辟 4 字節(jié)保存 10object obj num;裝箱在堆內存開辟一塊內存把棧里的 10 復制一份放到堆棧上 obj 變量保存堆中對象的地址裝箱 在堆包裝值類型變成引用對象。int num2 (int)obj;拆箱強制轉型檢查堆內 obj 里面存放的是不是 int如果類型匹配把堆里面的值拷貝回棧 num2 變量如果類型不匹配直接拋異常。? 拆箱必須拆回原本類型不能亂拆int num 10; object obj num; double d (double)obj; //運行報錯obj里面裝的是int不能直接拆成double注意拆箱必須先拆回原類型再做其他轉換。double d (double)(int)obj; //先拆箱為int再隱式轉為double? 裝箱拆箱使用場景老版本 API 接收 object 參數(shù)高頻循環(huán)盡量避免裝箱拆箱會帶來 GC 壓力。6. is 運算符 判斷類型as 安全引用類型轉換is判斷對象是不是某個類型返回 boolas嘗試把引用類型轉換轉換失敗不會拋異常得到 null。 ?? is 和 as只用于引用類型class、string不能用于值類型。示例 isobject obj Hello; if(obj is string) { Console.WriteLine(obj是字符串類型); }示例 asobject obj 測試文本; string str obj as string; if(str ! null) { Console.WriteLine(str); } //as失敗時strnull不會報錯對比強制轉型object obj 10; string s (string)obj; //強制轉換運行時報錯 string s2 obj as string; //as轉換失敗得到null不報錯7. 轉換方式對比總表轉換方式語法適用場景失敗表現(xiàn)隱式轉換直接賦值小范圍值類型 → 大范圍值類型編譯報錯不允許轉換強制轉型(目標類型)變量數(shù)字之間、裝箱拆箱溢出 / 類型不匹配運行報錯ConvertConvert.ToXXX()多類型互轉字符串轉數(shù)字失敗拋異常Parse類型.Parse (str)字符串→基礎類型失敗拋異常TryParse類型.TryParse (str,out var)用戶輸入字符串解析返回 false程序不崩潰asobj as 類型引用類型安全轉換失敗返回 null8. 新手高頻坑匯總(int)3.99直接截斷小數(shù)不是四舍五入想要四舍五入用Convert.ToInt32或者Math.Round不能用(int)123把字符串轉數(shù)字字符串和數(shù)字不兼容要用 Parse / Convert / TryParse拆箱必須拆回原始類型不能直接拆成別的類型隱式轉換只能從小→大大→小必須強制轉換只要是用戶輸入、外部讀取的字符串一律優(yōu)先 TryParse不要直接 Parse 和 Convert裝箱拆箱會產(chǎn)生堆對象大量循環(huán)中盡量減少as不能用于值類型is可以用于值類型判斷。