C 中As和強制轉換的總結

2021-12-29 22:41:50 字數 2938 閱讀 8092

1.1.1 摘要

c#是一門強型別語言,一般情況下,我們最好避免將乙個型別強制轉換為其他型別,但有些時候難免要進行型別轉換。

先想想究竟哪些操作可以進行型別轉換(先不考慮.net提供的parse),一般我們都有以下選擇:

使用as操作符轉換,

使用傳統c風格的強制轉型

使用is來做乙個轉換測試,然後再使用as操作符或者強制轉

1.1.2 正文

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

現在我們通過乙個簡單的例子說明as和強制轉換之間的區別,首先我們定義一間獲取不同型別物件的工廠,然後我們把未知型別轉換為自定義型別。

object o = factory.getobject();     

mytype t = o as mytype;  

if (t == null)

else

object o = factory.getobject();    

tryelse

}catch

通過上述**我們發現as型別轉換失敗時值為null不丟擲異常,但強制轉換如果轉換失敗會丟擲異常所以我們要新增異常處理。

現在我們對as和強制轉換有了初步的了解,假設現在我們定義了乙個抽象類foo,然後foo1繼承於它,並且再定義乙個基類logger,在foo1中定義與logger型別隱式轉換具體如下:

foo1 myfoo;          //// inherits abstract class.

logger myfoo;       //// base class.

public class foo1 : foo

}現在我們猜猜看以下的型別轉換是否成功(提示:從編譯和執行時型別轉換角度考慮)。

object myfoo = container.resolve();      //獲取未foo1型別

try}

catch

相信聰明的大家已經想出答案了,激動人心的時刻到了現在讓我們公布答案:轉換失敗丟擲異常。

圖1轉換失敗結果

首先我們要從編譯和執行時角度來分析,在編譯時myfoo的型別為system.object,這時編譯器會檢測是否存在自定義由object到logger的型別轉換。如果沒有找到合適轉換,編譯器將生成**檢測myfoo的執行時型別和logger比較,由於myfoo的執行時型別為foo1,而且我們自定義了由foo1到logger的型別轉換,估計這樣可以轉換成功了吧!然而恰恰沒有轉換成功,這究竟是什麼原因呢?讓我們了解一下編譯器對於隱式型別轉換的原理吧。

圖2編譯和執行時自定義型別轉換

通過上圖我們發現使用者自定義的轉換操作符只作用於物件的編譯時型別,而非執行時型別上,ok現在讓修改一下**讓我們編譯器認識自定義型別中。

using (iunitycontainer container = new unitycontainer())

}catch

console.readkey();

}圖3轉換成功結果

現在型別可以轉換成功,這是因為編譯器使用了我們自定義的隱式轉換,由於myfoo這次的編譯型別為foo1,編譯器首先查詢是否存在foo1和logger自定義轉換型別,由於我們定義了一種由foo1到logger的隱式型別轉換所以轉換成功。

通過上述我們發現了as給我們帶來的好處,但是有一點我們要注意的是as只能用於引用型別不能用於值型別。那我就有個問題了在進行型別轉換之前如果我們並不知道要轉換的是值型別還是引用型別,那該怎麼辦呢?現在是is登場的時候了。

bject tempfoo = container.resolve();      //獲取未foo1型別

int myint = tempfoo as int;                 //compile error

as不能用於值型別,這是因為值型別不能為null(注意:c#2.0中,微軟提供了nullable型別,允許用它定義包含null值,即空值的資料型別)像這種情況我們應該使用強制型別轉換。

object tempfoo = container.resolve();      //獲取未foo1型別

try}

catch

大家可以發現和我們之前使用的強制轉換類似,而且還有處理異常,現在修改一下我們**讓它更加簡潔實現如下:

object tempfoo = container.resolve();      //獲取未foo1型別

int i = 0;                                      //值型別轉換

if (tempfoo is int)

object tempfoo = container.resolve();      //獲取未foo1型別

logger myfoo1 = null;                          //引用型別轉換

if (tempfoo is logger)

1.1.3 總結

as和強制轉換之間最大的區別就在於如何處理使用者自定義的轉換。操作符 as和 is 都只檢查被轉換物件的執行時型別,並不執行其他的操作。如果被轉換物件的執行時型別既不是所轉換的目標型別,也不是其派生型別,那麼轉型將告失敗。但是強制轉型則會使用轉換操作符來執行轉型操作,這包括任何內建的數值轉換(如:long轉int)。

一般情況我們應該先考慮使用as進行型別轉換,然後再考慮使用is,最後才考慮使用強制轉換。

as強制轉換

轉換失敗是否丟擲異常

noyes

支援值型別和引用型別轉換

只支援引用型別

yes

C的強制轉換和C 的強制轉換

c的強制轉換 type 其中,type為型別描述符,如int,float等。為表示式。經強制型別轉換運算子運算後,返回乙個具有type型別的數值,這種強制型別轉換操作並不改變運算元本身,運算後運算元本身未改變,例如 int nvar 0xab65 char cchar char nvar 上述強制型...

c 中as和強制轉換區別

as和強制轉換之間最大的區別就在於如何處理使用者自定義的轉換。操作符 as和 is 都只檢查被轉換物件的執行時型別,並不執行其他的操作。如果被轉換物件的執行時型別既不是所轉換的目標型別,也不是其派生型別,那麼轉型將告失敗。但是強制轉型則會使用轉換操作符來執行轉型操作,這包括任何內建的數值轉換 如 l...

c 中的強制轉換

在c 中新添了四個關鍵字static cast,const cast,reinterpret cast和dynamic cast.這四個關鍵字都是用於強制型別轉換的。現在逐一介紹著四個關鍵字。在c 語言中static cast用於資料型別的強制轉換,強制將一種資料型別轉換為另一種資料型別,例如將資料...