日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
C#中As和強制轉(zhuǎn)換的總結(jié)

C#是一門強類型語言,一般情況下,我們***避免將一個類型強制轉(zhuǎn)換為其他類型,但有些時候難免要進行類型轉(zhuǎn)換。先想想究竟哪些操作可以進行類型轉(zhuǎn)換(先不考慮.NET提供的Parse),一般我們都有以下選擇:

創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計與策劃設(shè)計,福安網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:福安等地區(qū)。福安做網(wǎng)站價格咨詢:18980820575

  • 使用as操作符轉(zhuǎn)換,
  • 使用傳統(tǒng)C風(fēng)格的強制轉(zhuǎn)型,
  • 使用is來做一個轉(zhuǎn)換測試,然后再使用as操作符或者強制轉(zhuǎn)換。

正確的選擇應(yīng)該是盡可能地使用as操作符,因為它比強制轉(zhuǎn)型要安全,而且在運行時層面也有比較好的效率(注意的是as和is操作符都不執(zhí)行任何用戶自定義的轉(zhuǎn)換,只有當(dāng)運行時類型與目標(biāo)轉(zhuǎn)換類型匹配時,它們才會轉(zhuǎn)換成功)。

現(xiàn)在我們通過一個簡單的例子說明as和強制轉(zhuǎn)換之間的區(qū)別,首先我們定義一間獲取不同類型對象的工廠,然后我們把未知類型轉(zhuǎn)換為自定義類型。

 
 
 
  1. object o = Factory.GetObject();   
  2. MyType t = o as MyType;   
  3. if (t == null) { //轉(zhuǎn)換成功 }   
  4. else { //轉(zhuǎn)換失敗 }   
  5. object o = Factory.GetObject();   
  6. try { MyType t = o as MyType;   
  7. if (t != null)   
  8. { ////轉(zhuǎn)換成功   
  9. }   
  10. else   
  11. {   
  12. ////轉(zhuǎn)換失敗   
  13. }   
  14. }   
  15. catch   
  16. { ////異常處理  
  17.  } 

通過上述代碼我們發(fā)現(xiàn)as類型轉(zhuǎn)換失敗時值為null不拋出異常,但強制轉(zhuǎn)換如果轉(zhuǎn)換失敗會拋出異常所以我們要添加異常處理。

現(xiàn)在我們對as和強制轉(zhuǎn)換有了初步的了解,假設(shè)現(xiàn)在我們定義了一個抽象類Foo,然后Foo1繼承于它,并且再定義一個基類Logger,在Foo1中定義與Logger類型隱式轉(zhuǎn)換具體如下:

 
 
 
  1. Foo1 myFoo;  
  2. //// Inherits abstract class. Logger myFoo;   
  3. //// base class. public class Foo1 : Foo { PRivate Logger _value;   
  4. ///    
  5. /// 隱式自定義類型轉(zhuǎn)換。   
  6. ///    
  7. ///    
  8. ///    
  9. public static implicit Operator Logger(Foo1 foo1) { return foo1._value;   
  10. }   

現(xiàn)在我們猜猜看以下的類型轉(zhuǎn)換是否成功(提示:從編譯和運行時類型轉(zhuǎn)換角度考慮)。

 
 
 
  1. object myFoo = container.Resolve();   
  2. //獲取未Foo1類型   
  3. try { Logger myFoo1 = (Logger)myFoo;   
  4. if (myFoo1 != null)   
  5. {   
  6. Console.WriteLine("Covert successful.");   
  7. }   
  8. }   
  9. catch   
  10. {   
  11. Console.WriteLine("Covert failed.");   

相信聰明的大家已經(jīng)想出答案了,激動人心的時刻到了現(xiàn)在讓我們公布答案:轉(zhuǎn)換失敗拋出異常。

首先我們要從編譯和運行時角度來分析,在編譯時myFoo的類型為System.Object,這時編譯器會檢測是否存在自定義由Object到Logger的類型轉(zhuǎn)換。如果沒有找到合適轉(zhuǎn)換,編譯器將生成代碼檢測myFoo的運行時類型和Logger比較,由于myFoo的運行時類型為Foo1,而且我們自定義了由Foo1到Logger的類型轉(zhuǎn)換,估計這樣可以轉(zhuǎn)換成功了吧!然而恰恰沒有轉(zhuǎn)換成功,這究竟是什么原因呢?讓我們了解一下編譯器對于隱式類型轉(zhuǎn)換的原理吧。

通過我們發(fā)現(xiàn)用戶自定義的轉(zhuǎn)換操作符只作用于對象的編譯時類型,而非運行時類型上,OK現(xiàn)在讓修改一下代碼讓我們編譯器認識自定義類型中。

 
 
 
  1. using (IUnityContainer container = new UnityContainer()) 
  2. { UnityConfigurationSection 
  3. section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");   
  4. //獲取container名稱為CfgClass下的配置   
  5. section.Containers["CfgClass"].Configure(container);   
  6. object tempFoo = container.Resolve();   
  7. //獲取未Foo1類型   
  8. Foo1 myFoo = tempFoo as Foo1;   
  9. //使用as先把object轉(zhuǎn)型為Foo1   
  10. try { Logger myFoo1 = (Logger)myFoo;   
  11. if (myFoo1 != null) {   
  12. Console.WriteLine("Covert successful.");   
  13. }   
  14. }   
  15. catch {  
  16. Console.WriteLine("Covert failed.");   
  17. }   
  18. Console.ReadKey();   

現(xiàn)在類型可以轉(zhuǎn)換成功,這是因為編譯器使用了我們自定義的隱式轉(zhuǎn)換,由于myFoo這次的編譯類型為Foo1,編譯器首先查找是否存在Foo1和Logger自定義轉(zhuǎn)換類型,由于我們定義了一種由Foo1到Logger的隱式類型轉(zhuǎn)換所以轉(zhuǎn)換成功。

通過上述我們發(fā)現(xiàn)了as給我們帶來的好處,但是有一點我們要注意的是as只能用于引用類型不能用于值類型。那我就有個問題了在進行類型轉(zhuǎn)換之前如果我們并不知道要轉(zhuǎn)換的是值類型還是引用類型,那該怎么辦呢?現(xiàn)在是is登場的時候了。

 
 
 
  1. bject tempFoo = container.Resolve(); //獲取未Foo1類型   
  2. int myInt = tempFoo as int; //compile error 

as不能用于值類型,這是因為值類型不能為null(注意:C#2.0中,微軟提供了Nullable類型,允許用它定義包含null值,即空值的數(shù)據(jù)類型)像這種情況我們應(yīng)該使用強制類型轉(zhuǎn)換。

 
 
 
  1. object tempFoo = container.Resolve();   
  2. //獲取未Foo1類型   
  3. try { int myInt = (int)tempFoo;   
  4. //轉(zhuǎn)換成功   
  5. if (myFoo1 != null)   
  6. {   
  7. Console.WriteLine("Covert successful.");   
  8. }   
  9. }   
  10. catch   
  11. { Console.WriteLine("Covert failed.");   

大家可以發(fā)現(xiàn)和我們之前使用的強制轉(zhuǎn)換類似,而且還有處理異常,現(xiàn)在修改一下我們代碼讓它更加簡潔實現(xiàn)如下:

 
 
 
  1. object tempFoo = container.Resolve();   
  2. //獲取未Foo1類型int i = 0;   
  3. //值類型轉(zhuǎn)換  
  4. if (tempFoo is int){ i = (int) tempFoo;}  
  5. object tempFoo = container.Resolve();   
  6. //獲取未Foo1類型  
  7. Logger myFoo1 = null;   
  8. //引用類型轉(zhuǎn)換  
  9. if (tempFoo is Logger)  
  10. {   
  11. myFoo1 = tempFoo as Logger;  

總結(jié)

as和強制轉(zhuǎn)換之間***的區(qū)別就在于如何處理用戶自定義的轉(zhuǎn)換。操作符 as和 is 都只檢查被轉(zhuǎn)換對象的運行時類型,并不執(zhí)行其他的操作。如果被轉(zhuǎn)換對象的運行時類型既不是所轉(zhuǎn)換的目標(biāo)類型,也不是其派生類型,那么轉(zhuǎn)型將告失敗。但是強制轉(zhuǎn)型則會使用轉(zhuǎn)換操作符來執(zhí)行轉(zhuǎn)型操作,這包括任何內(nèi)建的數(shù)值轉(zhuǎn)換(如:long轉(zhuǎn)int)。

一般情況我們應(yīng)該先考慮使用as進行類型轉(zhuǎn)換,然后再考慮使用is,***才考慮使用強制轉(zhuǎn)換。


網(wǎng)站題目:C#中As和強制轉(zhuǎn)換的總結(jié)
鏈接分享:http://www.dlmjj.cn/article/dppdcsj.html