is 與 as

     我們知道C#是一種強類型的語言,這樣就可以保證在編譯的時候,發現類型不匹配的異常。這也說明了,我們應用程序在運行時不會去檢查類型的錯誤。但是,運行時檢查類型的錯誤有時候是不可避免的。在我們的程序中,經常會出現object 的參數,這時我們需要轉換成我們要求的類型或者接口。通常我們有兩種選擇:第一種是直接用as轉換或者進行強類型的轉換,第二種是先使用is進行類型判斷,再使用as轉換或者強類型轉換。

但是無論如何,我們都要選擇as,這比盲目強制的轉換要更加安全以及高效,同時as 和 is 不會執行任何用戶自定義的轉換,只有當目標類型和運行時類型匹配時纔會成功轉換。如下面:

object o = Factory.GetObject();
// Version one:
MyType t = o as MyType;
if (t != null)
{
// work with t, it's a MyType.
}
else
{
// report the failure.
}

object o = Factory.GetObject();
// Version two:
try
{
MyType t;
t = (MyType)o;
// work with T, it's a MyType.
}
catch (InvalidCastException)
{
// report the conversion failure.
}

顯而易見,我們會選擇第一種的轉換方式,第一種更加易讀並且未使用try catch來影響性能。另外我們看到as的操作,只需要判斷轉換後的結果是否爲NULL即可,而強類型的轉換不僅要判斷NULL,並且還需要捕獲異常。

cast轉換與as轉換最大的區別是:如何對待用戶自定義的轉換。對於is和as的操作來說,如果一個類型不是轉換要求的類型或者是其子類的話,轉換就會失敗。而強制類型轉換cast會利用轉換操作將原類型轉換爲目的類型,包含內嵌的數字類型。

public class SecondType
{
private MyType _value;
// other details elided
// Conversion operator.
// This converts a SecondType to
// a MyType, see item 9.
public static implicit operator
MyType(SecondType t)
{
return t._value;
}
}


object o = Factory.GetObject();
// o is a SecondType:
MyType t = o as MyType; // Fails. o is not MyType
if (t != null)
{
// work with t, it's a MyType.
}
else
{
// report the failure.
}


// Version two:
try
{
MyType t1;
t1 = (MyType)o; // Fails. o is not MyType
// work with t1, it's a MyType.
}
catch (InvalidCastException)
{
// report the conversion failure.
}

以上的兩種操作都會失敗,但是強制類型轉換會使用我們自定義的轉換操作。當然這種轉換也是失敗的,如下第三種轉換:

object o = Factory.GetObject();
// Version three:
SecondType st = o as SecondType;
try
{
MyType t;
t = (MyType)st;
// work with T, it's a MyType.
}
catch (InvalidCastException)
{
// report the failure.
}
記住:自定義的轉換操作只針對編譯時起作用,而非運行時。同時as轉換操作不能針對值類型,因爲值類型不能賦值爲NULL


謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章