在程式中,進行型別轉換時常見的事,c#支援基本的強制型別轉換方法,例如
object obj1 = new newtype();
newtype newvalue = (newtype)obj1;
這樣強制轉換的時候,這個過程是不安全的,因此需要用try-catch語句進行保護,這樣一來,比較安全的**方式應如下所示:
object obj1 = new newtype();
newtype newvalue = null;
trycatch (exception err)
但是上面的寫法在c#中已是過時的寫法,也是比較低效的寫法,比較高效且時尚的寫法是用as操作符,如下:
object obj1 = new newtype();
newtype newvalue = obj1 as newtype;
安全性:
as操作符不會做過的轉換操作,當需要轉化物件的型別屬於轉換目標型別或者轉換目標型別的派生型別時,那麼此轉換操作才能成功,而且並不產生新的物件【當不成功的時候,會返回null】。因此用as進行型別轉換是安全的。
效率:當用as操作符進行型別轉換的時候,首先判斷當前物件的型別,當型別滿足要求後才進行轉換,而傳統的型別轉換方式,是用當前物件直接去轉換,而且為了保護轉換成功,要加上try-catch,所以,相對來說,as效率高點。
需要注意的是,不管是傳統的還是as操作符進行型別轉換之後,在使用之前,需要進行判斷轉換是否成功,如下:
if(newvalue != null)
但是,使用as操作符要注意以下幾點:
1、不用在型別之間進行型別轉化,即如下編寫就會出現編譯錯誤。
newtype newvalue = new newtype();
newtype1 newvalue = newvalue as newtype1;
2、不能應用在值型別資料,即不能如下寫(也會出現編譯錯誤)
object obj1 = 11;
int nvalue = obj1 as int;
對於1.,可以用傳統的型別轉換方式完成:
newtypeone newtestone = new newtypeone();
newtypetwo newtesttwo = (newtypetwo)newtestone;
要想使上面的操作正確完成,在原有型別中增加型別轉換操作符函式,即需要完成類似如下的**:
public calss newtypeone
}
對於2,在c#中可以使用is操作符,再加上老式的型別轉換操作,就可以安全完成轉換,要完成如上操作,正確的寫法如下:
object obj1 = 11;
if(objtest is int )
在c#中提供的很好的型別轉換方式總結為:
object => 已知引用型別——使用as操作符完成;
object => 已知值型別——先使用is操作符來進行判斷,再用型別強轉換方式進行轉換;
已知引用型別之間轉換——首先需要相應型別提供轉換函式,再用型別強轉換方式進行轉換;
已知值型別之間轉換——最好使用系統提供的conver類所涉及的靜態方法。
is:檢查物件是否與給定的型別相容。例如,下面的**可以確定myobject型別的乙個例項,或者物件是否從myobject派生的乙個型別:
if(obj is myobject){}
如果所提供的表示式非空,並且所提供的物件可以強制轉換為所提供的型別而不會導致引發異常,則 is 表示式的計算結果將是 true。
如果已知表示式始終是true或始終是false,則is關鍵字將導致編譯時警告,但是通常在執行時才計算型別相容性。
注意:is執行符不能過載,is執行符只考慮引用轉換、裝箱轉換和取消裝箱轉換。不考慮其它轉換,如果使用者定義轉換。在is運算子的左側不允許使用匿名方法。lambda表示式屬於例外。
object myobject = new object();
boolean b1 = (myobject is object); true.
boolean b2 = (myobject is employee); false.
如果物件引用是null,is運算子總是返回false,因為沒有可檢查其型別的物件。
is運算子通常像下面這樣使用:
if (myobject is employee)
在這段**中,clr實際會檢查兩次物件的型別。is運算子首先核實myobject是否相容於employee型別。如果是,那麼在if語句內部執行轉換型,clr會再次核實myobject是否引用乙個employee。clr的型別檢查增加了安全性,但這樣對效能造成一定影響。這是因為clr首先必須判斷變數(myobject)引用的物件的實際型別。然後,clr必須遍歷繼承層次結構,用每個基型別去核對指定的型別(employee)。由於這是乙個相當常用的程式設計模式,所以c#專門提供了as運算子,目的就是簡化這種**寫法,同時提公升效能。
as:用於檢查在相容的引用型別之間執行某些型別的轉換。
employee myemployee = myobject as employee;
if (myemployee != null)
在這段**中,clr核實myobject是否相容於employee型別;如果是,as會返回對同乙個物件的乙個非null 的引用。如果myobject不相容於employee型別,as運算子會返回null。
注意:as運算子造成clr只校驗一次物件的型別。if語句只是檢查myemployee是否為null。這個檢查的速度比校驗物件的型別快得多。
as運算子的工作方式與強制型別轉換一樣,只是它永遠不會丟擲乙個異常。相反,如果物件不能轉換,結果就是null。所以,正確的做法是檢查最終生成的一引用是否為null。如果企圖直接使用最終生成的引用,會丟擲乙個system.nullreferenceexception異常。以下**對此進行了演示:
object o = new object(); 新建乙個object物件。
employee e = o as employee; 將o轉型為乙個employee
e.tostring(); 訪問e會丟擲乙個nullreferenceexception異常
備註:
as運算子類似於強制轉換操作。但是無法進行轉換,則as返回null而非引發異常。
示例:
expression as type它等效於以下表示式,但是只計算一次expression。
expression is type ?(type)expression : (type)null
注意:as運算子只執行引用轉換和裝箱轉換。as運算子無法執行其它轉換,如果使用者定義的轉換,這類轉換應使用強制轉換表示式來執行。 C 基礎 操作符過載
關於操作符過載,是c 乙個十分強大的功能。本文初略介紹下,涉及到友元以及函式過載 標頭檔案myclass.h ifndef myclass h define myclass h include include using namespace std class myclass myclass myc...
C 之操作符過載
1.所謂過載,就是賦予其新的意義。函式可以過載,操作符也可以過載。操作符的過載給我們的程式設計帶來了很大的便利,因為操作符只能對基本的資料型別進行操作,而對使用者自定義的類等資料結構型別不支援。因此只能對其操作符進行過載之後,才能更加方便地操作我們自定義的類物件等資料型別。但是值得注意的是並不是c ...
c 之操作符過載
include using namespace std class complex void printcom test add2 test t2 this 函式返回元素 complex operator complex c1 complex operator complex operator in...