明輝手游網(wǎng)中心:是一個免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

安全轉(zhuǎn)換參考型別(轉(zhuǎn))

[摘要]對初學(xué)者來說經(jīng)常造成初學(xué)者問題的是參考型別(reference types )的轉(zhuǎn)換(conversion),關(guān)於這點(diǎn)在C++ 造成相當(dāng)?shù)睦_更是如此,幸運(yùn)的是,在 C# 中不會發(fā)生。盡管是或是因為此種型別安全語言,對於不同的技術(shù)都應(yīng)該要有所認(rèn)識。轉(zhuǎn)型 is 運(yùn)算子 as 運(yùn)算子 為了能夠更清楚說...
對初學(xué)者來說經(jīng)常造成初學(xué)者問題的是參考型別(reference types )的轉(zhuǎn)換(conversion),關(guān)於這點(diǎn)在C++ 造成相當(dāng)?shù)睦_更是如此,幸運(yùn)的是,在 C# 中不會發(fā)生。盡管是或是因為此種型別安全語言,對於不同的技術(shù)都應(yīng)該要有所認(rèn)識。

轉(zhuǎn)型
is 運(yùn)算子
as 運(yùn)算子
為了能夠更清楚說明這個主題,我選擇一個很不錯的例子:我們試著將 apples 轉(zhuǎn)換成 oranges - 某些地方是 C# 不允許的(因此較適合用來說明如何處理轉(zhuǎn)換錯誤) 所有範(fàn)例的基本程式碼架構(gòu)如下 (classes.aspx):

<script language=c# runat=server>
class apple
{
public string Fruit() { return "Apple"; }
}

class orange
{
public string Fruit() { return "Orange"; }
}
</script>
<% @page language=c# %>
<%
apple myApple = new apple();
orange myOrange = new orange();
Response.Write(myApple.Fruit()+"<br>");
Response.Write(myOrange.Fruit()+"<br>");
%>

轉(zhuǎn)型 (Casting)
即使我們會失敗,我們所先會試著去解決:

apple myApple = new apple();
orange anotherOrange = (orange)myApple;

上面程式碼編譯器會抱怨:它知道這個轉(zhuǎn)換是無效的,甚至不會去編譯程式碼。 理由很清楚,就是 apple class 與 orange class 根本沒有相同之處。

所以我們將選擇另一個較實際的方法 - 首先將型別存放在一般 object 變數(shù)中(例如當(dāng)將元素存放在堆疊 (Stack),Queues 或 ArrayLists 中), 之後在轉(zhuǎn)換成可再使用的適當(dāng)型別:

apple myApple = new apple();
// the following line stands for potentially more complicated operations
object objGeneral = myApple;
orange anotherOrange = (orange)objGeneral;

當(dāng)選擇了錯誤型別 - 就如我們所做的,C# 可能就不允許這樣 - 也就是說在執(zhí)行時期可藉由InvalidCastException,要能適當(dāng)捕獲錯誤,例外處理程式碼是必須的,例如:

apple myApple = new apple();
object objGeneral = myApple;
try
{
 orange anotherOrange = (orange)objGeneral;
 // do whatever you want with the orange
}
catch(InvalidCastException e)
{
 // either do nothing or tell the user
}

即使是所有的錯誤都處理了,在這例外處理中我只發(fā)現(xiàn)到一失敗地方。如果我能夠事先的 要求轉(zhuǎn)型是否成功,可能情況會更好更方便。這也就是為何 is 運(yùn)算子會派上用場之處。

is 運(yùn)算子
因為已經(jīng)宣告了,is 運(yùn)算子允許要求轉(zhuǎn)型是否成功或是產(chǎn)生例外。 下面這段小程式說明 is 運(yùn)算子如何在應(yīng)用程式中使用:

apple myApple = new apple();
object objGeneral = myApple;

if (objGeneral is orange)
{
 orange anotherOrange = (orange)objGeneral;
 // do whatever you want with the orange
}
else
{
 Response.Write("this is no orange");
}

我想給一個關(guān)於is 運(yùn)算子的提示 - 如果在編譯執(zhí)行時候可以決定轉(zhuǎn)換 不是成功就是失敗的話 - 關(guān)於這一點(diǎn)我們很遺憾的是在 ASP.NET 看不到。

as 運(yùn)算子
as 運(yùn)算子可以稱作是 exception-less cast。轉(zhuǎn)換會暗地執(zhí)行 - 萬一轉(zhuǎn)換失敗,要轉(zhuǎn)換的目標(biāo)變數(shù)就會設(shè)成null。所有剩下的工作就 是使用 if-statement 陳述來檢查這個變數(shù):

apple myApple = new apple();
object objGeneral = myApple;

orange anotherOrange;
anotherOrange = objGeneral as orange;
if (null != anotherOrange)
{
 // do whatever you want with the orange
}
else
{
 Response.Write("this is no orange");
}

對 as 運(yùn)算子來說道理就如同 is 運(yùn)算子一樣 - 如果轉(zhuǎn)換成功或是失敗,你會收到警告訊息。 例如這個程式碼:

apple myApple = new apple;
apple anotherApple = myApple as apple;

結(jié)論
條條道路通羅馬,到羅馬的道路可以有好幾條路,然而有些道路會比其他道路曲折。 對於型別轉(zhuǎn)換我個人最喜歡的方法是用 is運(yùn)算子。