詳解c# 強(qiáng)制轉(zhuǎn)換和類(lèi)型轉(zhuǎn)換
由于 C# 是在編譯時(shí)靜態(tài)類(lèi)型化的,因此變量在聲明后就無(wú)法再次聲明,或無(wú)法分配另一種類(lèi)型的值,除非該類(lèi)型可以隱式轉(zhuǎn)換為變量的類(lèi)型。 例如,string 無(wú)法隱式轉(zhuǎn)換為 int。 因此,在將 i 聲明為 int 后,無(wú)法將字符串“Hello”分配給它,如以下代碼所示:
int i; // error CS0029: Cannot implicitly convert type 'string' to 'int' i = "Hello";
但有時(shí)可能需要將值復(fù)制到其他類(lèi)型的變量或方法參數(shù)中。 例如,可能需要將一個(gè)整數(shù)變量傳遞給參數(shù)類(lèi)型化為 double 的方法。 或者可能需要將類(lèi)變量分配給接口類(lèi)型的變量。 這些類(lèi)型的操作稱(chēng)為類(lèi)型轉(zhuǎn)換。 在 C# 中,可以執(zhí)行以下幾種類(lèi)型的轉(zhuǎn)換:
- 隱式轉(zhuǎn)換:由于這種轉(zhuǎn)換始終會(huì)成功且不會(huì)導(dǎo)致數(shù)據(jù)丟失,因此無(wú)需使用任何特殊語(yǔ)法。 示例包括從較小整數(shù)類(lèi)型到較大整數(shù)類(lèi)型的轉(zhuǎn)換以及從派生類(lèi)到基類(lèi)的轉(zhuǎn)換。
- 顯式轉(zhuǎn)換(強(qiáng)制轉(zhuǎn)換) :必須使用強(qiáng)制轉(zhuǎn)換表達(dá)式,才能執(zhí)行顯式轉(zhuǎn)換。 在轉(zhuǎn)換中可能丟失信息時(shí)或在出于其他原因轉(zhuǎn)換可能不成功時(shí),必須進(jìn)行強(qiáng)制轉(zhuǎn)換。 典型的示例包括從數(shù)值到精度較低或范圍較小的類(lèi)型的轉(zhuǎn)換和從基類(lèi)實(shí)例到派生類(lèi)的轉(zhuǎn)換。
- 用戶(hù)定義的轉(zhuǎn)換:用戶(hù)定義的轉(zhuǎn)換是使用特殊方法執(zhí)行,這些方法可定義為在沒(méi)有基類(lèi)和派生類(lèi)關(guān)系的自定義類(lèi)型之間啟用顯式轉(zhuǎn)換和隱式轉(zhuǎn)換。
- 使用幫助程序類(lèi)進(jìn)行轉(zhuǎn)換:若要在非兼容類(lèi)型(如整數(shù)和 System.DateTime 對(duì)象,或十六進(jìn)制字符串和字節(jié)數(shù)組)之間轉(zhuǎn)換,可使用 System.BitConverter 類(lèi)、System.Convert 類(lèi)和內(nèi)置數(shù)值類(lèi)型的 Parse 方法(如 Int32.Parse)。
隱式轉(zhuǎn)換
對(duì)于內(nèi)置數(shù)值類(lèi)型,如果要存儲(chǔ)的值無(wú)需截?cái)嗷蛩纳嵛迦爰纯蛇m應(yīng)變量,則可以進(jìn)行隱式轉(zhuǎn)換。 對(duì)于整型類(lèi)型,這意味著源類(lèi)型的范圍是目標(biāo)類(lèi)型范圍的正確子集。 例如,long 類(lèi)型的變量(64 位整數(shù))能夠存儲(chǔ) int(32 位整數(shù))可存儲(chǔ)的任何值。 在下面的示例中,編譯器先將右側(cè)的 num 值隱式轉(zhuǎn)換為 long 類(lèi)型,再將它賦給 bigNum。
// Implicit conversion. A long can // hold any value an int can hold, and more! int num = 2147483647; long bigNum = num;
有關(guān)所有隱式數(shù)值轉(zhuǎn)換的完整列表,請(qǐng)參閱內(nèi)置數(shù)值轉(zhuǎn)換一文的隱式數(shù)值轉(zhuǎn)換表部分。
對(duì)于引用類(lèi)型,隱式轉(zhuǎn)換始終存在于從一個(gè)類(lèi)轉(zhuǎn)換為該類(lèi)的任何一個(gè)直接或間接的基類(lèi)或接口的情況。 由于派生類(lèi)始終包含基類(lèi)的所有成員,因此不必使用任何特殊語(yǔ)法。
Derived d = new Derived(); // Always OK. Base b = d;
顯式轉(zhuǎn)換
但是,如果進(jìn)行轉(zhuǎn)換可能會(huì)導(dǎo)致信息丟失,則編譯器會(huì)要求執(zhí)行顯式轉(zhuǎn)換,顯式轉(zhuǎn)換也稱(chēng)為強(qiáng)制轉(zhuǎn)換。 強(qiáng)制轉(zhuǎn)換是顯式告知編譯器以下信息的一種方式:你打算進(jìn)行轉(zhuǎn)換且你知道可能會(huì)發(fā)生數(shù)據(jù)丟失,或者你知道強(qiáng)制轉(zhuǎn)換有可能在運(yùn)行時(shí)失敗。 若要執(zhí)行強(qiáng)制轉(zhuǎn)換,請(qǐng)?jiān)谝D(zhuǎn)換的值或變量前面的括號(hào)中指定要強(qiáng)制轉(zhuǎn)換到的類(lèi)型。 下面的程序?qū)?double 強(qiáng)制轉(zhuǎn)換為 int。如不強(qiáng)制轉(zhuǎn)換則該程序不會(huì)進(jìn)行編譯。
class Test { static void Main() { double x = 1234.7; int a; // Cast double to int. a = (int)x; System.Console.WriteLine(a); } } // Output: 1234
有關(guān)支持的顯式數(shù)值轉(zhuǎn)換的完整列表,請(qǐng)參閱內(nèi)置數(shù)值轉(zhuǎn)換一文的顯式數(shù)值轉(zhuǎn)換部分。
對(duì)于引用類(lèi)型,如果需要從基類(lèi)型轉(zhuǎn)換為派生類(lèi)型,則必須進(jìn)行顯式強(qiáng)制轉(zhuǎn)換:
// Create a new derived type. Giraffe g = new Giraffe(); // Implicit conversion to base type is safe. Animal a = g; // Explicit conversion is required to cast back // to derived type. Note: This will compile but will // throw an exception at run time if the right-side // object is not in fact a Giraffe. Giraffe g2 = (Giraffe)a;
引用類(lèi)型之間的強(qiáng)制轉(zhuǎn)換操作不會(huì)更改基礎(chǔ)對(duì)象的運(yùn)行時(shí)類(lèi)型;它只更改用作對(duì)該對(duì)象引用的值的類(lèi)型。 有關(guān)詳細(xì)信息,請(qǐng)參閱多態(tài)性。
運(yùn)行時(shí)的類(lèi)型轉(zhuǎn)換異常
在某些引用類(lèi)型轉(zhuǎn)換中,編譯器無(wú)法確定強(qiáng)制轉(zhuǎn)換是否會(huì)有效。 正確進(jìn)行編譯的強(qiáng)制轉(zhuǎn)換操作有可能在運(yùn)行時(shí)失敗。 如下面的示例所示,類(lèi)型轉(zhuǎn)換在運(yùn)行時(shí)失敗將導(dǎo)致引發(fā) InvalidCastException。
class Animal { public void Eat() => System.Console.WriteLine("Eating."); public override string ToString() => "I am an animal."; } class Reptile : Animal { } class Mammal : Animal { } class UnSafeCast { static void Main() { Test(new Mammal()); // Keep the console window open in debug mode. System.Console.WriteLine("Press any key to exit."); System.Console.ReadKey(); } static void Test(Animal a) { // System.InvalidCastException at run time // Unable to cast object of type 'Mammal' to type 'Reptile' Reptile r = (Reptile)a; } }
Test 方法有一個(gè) Animal 形式參數(shù),因此,將實(shí)際參數(shù) a 顯式強(qiáng)制轉(zhuǎn)換為 Reptile 會(huì)造成危險(xiǎn)的假設(shè)。 更安全的做法是不要做出假設(shè),而是檢查類(lèi)型。 C# 提供 is 運(yùn)算符,使你可以在實(shí)際執(zhí)行強(qiáng)制轉(zhuǎn)換之前測(cè)試兼容性。 有關(guān)詳細(xì)信息,請(qǐng)參閱如何使用模式匹配以及 as 和 is 運(yùn)算符安全地進(jìn)行強(qiáng)制轉(zhuǎn)換。
以上就是詳解c# 強(qiáng)制轉(zhuǎn)換和類(lèi)型轉(zhuǎn)換的詳細(xì)內(nèi)容,更多關(guān)于c# 強(qiáng)制轉(zhuǎn)換和類(lèi)型轉(zhuǎn)換的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- C#中的自動(dòng)類(lèi)型轉(zhuǎn)換和強(qiáng)制類(lèi)型轉(zhuǎn)換
- C# 數(shù)據(jù)類(lèi)型轉(zhuǎn)換
- C#數(shù)據(jù)類(lèi)型轉(zhuǎn)換(顯式轉(zhuǎn)型、隱式轉(zhuǎn)型、強(qiáng)制轉(zhuǎn)型)
- C#類(lèi)型轉(zhuǎn)換之自定義隱式轉(zhuǎn)換和顯式轉(zhuǎn)換
- C#實(shí)現(xiàn)數(shù)組元素的數(shù)據(jù)類(lèi)型轉(zhuǎn)換方法詳解
- C#預(yù)定義的基礎(chǔ)類(lèi)型轉(zhuǎn)換
- 詳解C#如何實(shí)現(xiàn)隱式類(lèi)型轉(zhuǎn)換
- C#避免類(lèi)型轉(zhuǎn)換異常的三種方法
- C# 類(lèi)型轉(zhuǎn)換(隱式類(lèi)型,顯式類(lèi)型,自定義類(lèi)型)
相關(guān)文章
c#中DataTable轉(zhuǎn)List的2種方法示例
這篇文章主要給大家介紹了關(guān)于c#中DataTable轉(zhuǎn)List的2種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04C#操作數(shù)據(jù)庫(kù)中存取圖片文件的方法
這篇文章主要介紹了C#操作數(shù)據(jù)庫(kù)中存取圖片文件的方法,以實(shí)例形式分析了C#將圖片存入數(shù)據(jù)庫(kù)及從數(shù)據(jù)庫(kù)讀取圖片文件的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10C#中DataGridView導(dǎo)出Excel的兩種方法
這篇文章主要介紹了C#中DataGridView導(dǎo)出Excel的兩種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01C#實(shí)現(xiàn)讀取和設(shè)置文件與文件夾的權(quán)限
這篇文章主要為大家詳細(xì)介紹了如何使用C#實(shí)現(xiàn)讀取和設(shè)置文件與文件夾的權(quán)限,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03C#線(xiàn)程處理系列之線(xiàn)程池中的I/O線(xiàn)程
這篇文章主要介紹了C#線(xiàn)程處理系列之線(xiàn)程池中的I/O線(xiàn)程,在這篇文章中將介紹如何用線(xiàn)程池中的I/O線(xiàn)程來(lái)執(zhí)行I/O操作,感興趣的小伙伴們可以參考一下2016-04-04