C#中的is, as 和 cast

C#做爲靜態強類型語言,要想使用好它,掌握好幾種類型判斷的方法是很基礎也很必要的。如咱們所知,最經常使用的幾種就是,isas鑄型cast和自定義類型轉換。可是這幾種之間有什麼區別是一個容易混淆的地方,如今讓咱們來看看。安全

is

is以下場合返回true:測試

  • 實例屬於該類型
class Person { }
   		Person p = new Person();
   		bool result = p is Person;
複製代碼
  • 實例屬於該類型的派生類型
class Manager : Person { }
   		Manager m = new Manager();
   		bool result = m is Person;
複製代碼
  • 實例實現了該接口
interface IEmpty { }
                class ImplememntEmpty : IEmpty { }
                ImplememntEmpty instance = new ImplememntEmpty();
                var result = instance is IEmpty;
複製代碼
  • 實例拆箱以後類型能夠匹配
var obj = 10l;
   		var result = obj is long;
複製代碼

注意,is關鍵字不會考慮用戶自定的類型轉換,不管是implicit仍是explicit都不會考慮。  spa

as

as關鍵字和is牢牢關聯,在內部,as關鍵字是這麼處理的,code

instace is type ? (type)instance : (type)null 
複製代碼

因此在使用as的時候,有兩個地方須要注意。接口

  • 要想經過as完成轉型,首先要確保實例能經過is測試,也就是說,用戶自定義的類型轉換仍是不會被考慮。
  • as轉型失敗的時候會返回一個null,因此as的目標必須是能引用類型或者是可空值類型,不然編譯器會報錯。考慮下面這個例子,
object obj = 10l;
                        var result = obj as long; //這裏會報錯
複製代碼

正確的寫法是ci

object obj = 10l;
                        var result = obj as long?; //這裏就沒問題了,這樣確保了在轉型失敗的狀況下,null能夠賦值給long?
複製代碼

 

cast

cast分爲顯式轉型和隱式轉型,當編譯器檢測出轉型不會形成數據精度損失,或者不會有轉型風險的時候,不須要使用顯式轉型,反之,若是顯式轉型是必須的。編譯器

  • 對於值類型來講,從低精度到高精度的轉型被視做無精度損失,是安全的,好比從int到long, 從float到double。反之則須要顯式轉型,旨在告訴編譯器用戶知曉這種轉型可能會影響精度,用戶甘願接受這種精度損失。
float f = 10;
            double d = f;
            int i = 10;
            long l = i;

			//下面開始是顯式轉型
            i = (int)l;
            f = (float)d;
複製代碼
  • 對於引用類型來講,從子類像父類的轉換老是安全的,成功的,這裏不須要顯式轉型。可是反過來,顯式轉型是須要的,由於從父類轉換到子類不老是會成功。
class Person { }
			class Manager : Person { }

			Manager m = new Manager();
                        Person p = m;
			
			//如下須要顯式轉型,請注意,在這裏若是p不是一個Manager,顯式轉型會拋異常。因此在使用顯式轉型的地方,建議使用as或者加入try catch以增長代碼安全
			m = (Manager)p;
複製代碼

 

用戶自定義類型轉換

上面的Cast可使用到用戶自定義類型轉換,和Cast有顯式和隱式同樣,用戶自定義類型轉換也有顯式隱式之分。分別用關鍵字explicitimplicit區分,在調用的時候,顯式轉換可使用用戶自定義的顯式和隱式轉換,而隱式轉換就要求用戶必須提供自定義的隱式轉換。 用戶自定義類型轉換的做用在於給本來可能風馬牛不相及的類型之間提供了一個轉換通道,讓它們相互轉換成爲了可能,而這一切,在自定義類型轉換出來以前,極可能是編譯器禁止的。it

class Company { }
			class Corporation { }
			Company c = new Company();
                        Corporation cor = (Corporation)c; //編譯器會報錯,聲稱沒法將Company類型轉換成Corporation
複製代碼

添加顯式自定義類型轉換io

class Company 
			{ 
				public static explicit operator Corporation(Company c) {
                            	    return new Corporation();
                        	}
  			}
複製代碼

這樣編譯器就能知道咱們提供了一個自定義轉換從Company到Corporation,這樣上面那段代碼就能夠工做了。 隱式用戶自定義轉換相似,只是把關鍵字explicit換成implicit便可。編譯

相關文章
相關標籤/搜索