在C#中,當(dāng)引用類型需要轉(zhuǎn)換的時候,經(jīng)常會用到關(guān)鍵字is、as以及顯式強轉(zhuǎn)。本篇來體驗這三者的用法。
先來梳理.NET引用類型轉(zhuǎn)換的"約定俗成",或者叫"慣例":● 子類可以隱式轉(zhuǎn)換為父類/基類,也就是"里氏替換原則"所說的:子類必須能夠替換其父類/基類。● 父類/基類轉(zhuǎn)換為子類時,必須進(jìn)行顯式類型強轉(zhuǎn)。
子類轉(zhuǎn)換成父類
class PRogram { static void Main(string[] args) { Animal animal = new Dog(){Name = "Dog",Age = 1}; Console.WriteLine(animal.Name); Console.ReadKey(); } } public class Animal { public string Name { get; set; } } public class Dog : Animal { public int Age { get; set; } }
輸出結(jié)果:Dog
以上,體驗了子類轉(zhuǎn)換成父類,從中可以看出:子類Dog確實能替換父類Animal,換句話說,子類就是父類,子類的實例可以賦值給父類的變量,不需要as,不需要強轉(zhuǎn),一切都是隱式發(fā)生,很好地體現(xiàn)了"里氏替換原則"。
父類轉(zhuǎn)換為子類,父類變量通過子類賦值而創(chuàng)建
父類as成子類:
Animal animal = new Dog(){Name = "Dog",Age = 1}; Dog dog = animal as Dog; Console.WriteLine(dog.Name + " " + dog.Age); Console.ReadKey();輸出結(jié)果:Dog 1
父類顯式強轉(zhuǎn)成子類
Animal animal = new Dog(){Name = "Dog",Age = 1}; Dog dog = (Dog)animal; Console.WriteLine(dog.Name + " " + dog.Age); Console.ReadKey();輸出結(jié)果:Dog 1
以上,不管是使用as還是顯式強轉(zhuǎn),父類都可以轉(zhuǎn)換成子類,但是有前提的:把子類實例賦值給父類變量。
父類轉(zhuǎn)換為子類,父類變量通過自身構(gòu)造函數(shù)而創(chuàng)建
父類as成子類失敗:
Animal animal = new Animal(){Name = "Sheep"}; Dog dog = animal as Dog; Console.WriteLine(dog.Name + " " + dog.Age); Console.ReadKey();輸出結(jié)果:報"NullReferenceException"錯
可見,當(dāng)父類變量通過自身構(gòu)造函數(shù)而創(chuàng)建時,無法將父類轉(zhuǎn)換成子類。
(1)為了避免as的時候報"NullReferenceException"錯,引入關(guān)鍵is做類型判斷:
Animal animal = new Animal(){Name = "Sheep"}; if (animal is Dog) { Dog dog = animal as Dog; Console.WriteLine(dog.Name + " " + dog.Age); } else { Console.WriteLine("animal不能轉(zhuǎn)換為Dog"); } Console.ReadKey();輸出結(jié)果:animal不能轉(zhuǎn)換為Dog
(2)用as做類型轉(zhuǎn)換的時候,如果轉(zhuǎn)換失敗,返回null。根據(jù)這點,也可以通過判斷as轉(zhuǎn)換后的返回值是否為null,來避免報錯:
Animal animal = new Animal(){Name = "Sheep"}; Dog dog = animal as Dog; if (dog != null) { Console.WriteLine(dog.Name + " " + dog.Age); } else { Console.WriteLine("animal不能轉(zhuǎn)換為Dog"); } Console.ReadKey();輸出結(jié)果:animal不能轉(zhuǎn)換為Dog
父類顯式強轉(zhuǎn)成子類失敗
Animal animal = new Animal(){Name = "Sheep"}; Dog dog = (Dog) animal; Console.WriteLine(dog.Name + " " + dog.Age); Console.ReadKey();輸出結(jié)果:報"InvalidCastException"錯
可見,當(dāng)父類變量通過自身構(gòu)造函數(shù)而創(chuàng)建時,無法將父類轉(zhuǎn)換成子類。
為了避免顯示強轉(zhuǎn)時報"InvalidCastException"錯,引入關(guān)鍵字is做類型判斷:
Animal animal = new Animal(){Name = "Sheep"}; if (animal is Dog) { Dog dog = (Dog)animal; Console.WriteLine(dog.Name + " " + dog.Age); } else { Console.WriteLine("animal不能轉(zhuǎn)換為Dog"); } Console.ReadKey();輸出結(jié)果:animal不能轉(zhuǎn)換為Dog
總結(jié)
● 對于引用類型的轉(zhuǎn)換,應(yīng)該考慮使用顯式強轉(zhuǎn)或as。兩者的區(qū)別在于:一旦類型無法轉(zhuǎn)換,使用顯式強轉(zhuǎn)會報錯,而使用as會返回null?!?為了避免顯式強轉(zhuǎn)或as所引發(fā)的報錯,應(yīng)該考慮使用is來判斷類型間是否能轉(zhuǎn)換?!?使用as進(jìn)行引用類型轉(zhuǎn)換,不僅可以用is來判斷類型間是否能轉(zhuǎn)換,還可以通過判斷as后的返回值是否為null,然后采取相應(yīng)的操作?!?對于基本類型的轉(zhuǎn)換:使用Convert, Parse, TryParse等。
is用于判斷類型是否一致,as和顯式強轉(zhuǎn)用于類型的轉(zhuǎn)換。
新聞熱點
疑難解答