在C#中,接口是一個比較特殊的存在,一個接口的實例,可以轉換為沒有實現該接口的類,並且不會發生編譯錯誤。
為此,我們新建一個.NET Core控制台項目,然后使用如下代碼來進行實驗:
using System; namespace NetCoreInterfaceTypeConversion { //接口IPeople interface IPeople { } //結構體PeopleStruct,沒有實現接口IPeople struct PeopleStruct //: IPeople { } //抽象類PeopleAbstractClass,沒有實現接口IPeople abstract class PeopleAbstractClass { } //類PeopleClass,沒有實現接口IPeople class PeopleClass //: PeopleAbstractClass { } //類PeopleImplementedIPeopleClass,實現了接口IPeople class PeopleImplementedIPeopleClass : IPeople { } class Program { static void Main(string[] args) { ConsoleColor defaultColor = Console.ForegroundColor; IPeople iPeople = null; Console.WriteLine("============================================="); Console.WriteLine("接口IPeople和結構體PeopleStruct轉換測試:"); Console.WriteLine("============================================="); //PeopleStruct peopleStruct = (PeopleStruct)iPeople;//如果結構體PeopleStruct沒有實現接口IPeople,那么接口IPeople的實例iPeople,無法使用類型轉換為結構體類型PeopleStruct,編譯時會報錯 Console.WriteLine("iPeople是PeopleStruct結構體嗎?{0}", (iPeople is PeopleStruct).ToString());//False PeopleStruct peopleStruct = new PeopleStruct(); //iPeople = (IPeople)peopleStruct;//同理,因為結構體PeopleStruct沒有實現接口IPeople,所以結構體PeopleStruct的實例peopleStruct,無法使用類型轉換為接口類型IPeople,編譯時會報錯 //iPeople = peopleStruct as IPeople;//同理,因為結構體PeopleStruct沒有實現接口IPeople,所以結構體PeopleStruct的實例peopleStruct,無法使用as關鍵字轉換為接口類型IPeople,編譯時會報錯 Console.WriteLine("peopleStruct是IPeople類型嗎?{0}", (peopleStruct is IPeople).ToString());//False Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("iPeople為null,iPeople使用類型轉換為PeopleAbstractClass和PeopleClass類型:"); Console.WriteLine("============================================="); iPeople = null; PeopleAbstractClass peopleAbstractClass = (PeopleAbstractClass)iPeople; PeopleClass peopleClass = (PeopleClass)iPeople; Console.WriteLine("peopleAbstractClass為null嗎?{0}", (peopleAbstractClass == null).ToString());//True Console.WriteLine("peopleClass為null嗎?{0}", (peopleClass == null).ToString());//True Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("iPeople為null,iPeople使用as關鍵字轉換為PeopleAbstractClass和PeopleClass類型:"); Console.WriteLine("============================================="); iPeople = null; peopleAbstractClass = iPeople as PeopleAbstractClass; peopleClass = iPeople as PeopleClass; Console.WriteLine("peopleAbstractClass為null嗎?{0}", (peopleAbstractClass == null).ToString());//True Console.WriteLine("peopleClass為null嗎?{0}", (peopleClass == null).ToString());//True Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("iPeople為null,iPeople使用is關鍵字判斷是否為PeopleAbstractClass和PeopleClass類型:"); Console.WriteLine("============================================="); iPeople = null; Console.WriteLine("iPeople是PeopleAbstractClass類型嗎?{0}", (iPeople is PeopleAbstractClass).ToString());//False Console.WriteLine("iPeople是PeopleClass類型嗎?{0}", (iPeople is PeopleClass).ToString());//False Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("iPeople為PeopleImplementedIPeopleClass類型的實例對象,iPeople使用類型轉換為PeopleAbstractClass和PeopleClass類型:"); Console.WriteLine("============================================="); iPeople = new PeopleImplementedIPeopleClass(); try { peopleAbstractClass = (PeopleAbstractClass)iPeople;//此時因為iPeople不為null了,所以類型轉換為沒有繼承關系的PeopleAbstractClass類時,會發生InvalidCastException異常 } catch (InvalidCastException) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("iPeople為PeopleImplementedIPeopleClass類型的實例對象,使用類型轉換為PeopleAbstractClass類型,發生了InvalidCastException異常"); Console.ForegroundColor = defaultColor; } try { peopleClass = (PeopleClass)iPeople;//此時因為iPeople不為null了,所以類型轉換為沒有繼承關系的PeopleClass類時,會發生InvalidCastException異常 } catch (InvalidCastException) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("iPeople為PeopleImplementedIPeopleClass類型的實例對象,使用類型轉換為PeopleClass類型,發生了InvalidCastException異常"); Console.ForegroundColor = defaultColor; } Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("iPeople為PeopleImplementedIPeopleClass類型的實例對象,iPeople使用as關鍵字轉換為PeopleAbstractClass和PeopleClass類型:"); Console.WriteLine("============================================="); iPeople = new PeopleImplementedIPeopleClass(); peopleAbstractClass = iPeople as PeopleAbstractClass; peopleClass = iPeople as PeopleClass; Console.WriteLine("peopleAbstractClass為null嗎?{0}", (peopleAbstractClass == null).ToString());//True Console.WriteLine("peopleClass為null嗎?{0}", (peopleClass == null).ToString());//True Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("iPeople為PeopleImplementedIPeopleClass類型的實例對象,iPeople使用is關鍵字判斷是否為PeopleAbstractClass和PeopleClass類型:"); Console.WriteLine("============================================="); iPeople = new PeopleImplementedIPeopleClass(); Console.WriteLine("iPeople是PeopleAbstractClass類型嗎?{0}", (iPeople is PeopleAbstractClass).ToString());//False Console.WriteLine("iPeople是PeopleClass類型嗎?{0}", (iPeople is PeopleClass).ToString());//False Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("peopleAbstractClass為null,peopleClass為null,peopleAbstractClass和peopleClass使用類型轉換為IPeople類型:"); Console.WriteLine("============================================="); peopleAbstractClass = null; peopleClass = null; iPeople = (IPeople)peopleAbstractClass; Console.WriteLine("iPeople為null嗎?{0}", (iPeople == null).ToString());//True iPeople = (IPeople)peopleClass; Console.WriteLine("iPeople為null嗎?{0}", (iPeople == null).ToString());//True Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("peopleAbstractClass為null,peopleClass為null,peopleAbstractClass和peopleClass使用as關鍵字轉換為IPeople類型:"); Console.WriteLine("============================================="); peopleAbstractClass = null; peopleClass = null; iPeople = peopleAbstractClass as IPeople; Console.WriteLine("iPeople為null嗎?{0}", (iPeople == null).ToString());//True iPeople = peopleClass as IPeople; Console.WriteLine("iPeople為null嗎?{0}", (iPeople == null).ToString());//True Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("peopleAbstractClass為null,peopleClass為null,peopleAbstractClass和peopleClass使用is關鍵字判斷是否為IPeople類型:"); Console.WriteLine("============================================="); peopleAbstractClass = null; peopleClass = null; Console.WriteLine("peopleAbstractClass是IPeople類型嗎?{0}", (peopleAbstractClass is IPeople).ToString());//False Console.WriteLine("peopleClass是IPeople類型嗎?{0}", (peopleClass is IPeople).ToString());//False Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("peopleClass為PeopleClass類型的實例對象,peopleClass使用類型轉換為IPeople類型:"); Console.WriteLine("============================================="); peopleClass = new PeopleClass(); try { iPeople = (IPeople)peopleClass;//此時因為peopleClass不為null了,所以類型轉換為沒有繼承關系的IPeople接口時,會發生InvalidCastException異常 } catch (InvalidCastException) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("peopleClass為PeopleClass類型的實例對象,使用類型轉換為IPeople類型,發生了InvalidCastException異常"); Console.ForegroundColor = defaultColor; } Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("peopleClass為PeopleClass類型的實例對象,peopleClass使用as關鍵字轉換為IPeople類型:"); Console.WriteLine("============================================="); peopleClass = new PeopleClass(); iPeople = peopleClass as IPeople; Console.WriteLine("iPeople為null嗎?{0}", (iPeople == null).ToString());//True Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("peopleClass為PeopleClass類型的實例對象,peopleClass使用is關鍵字判斷是否為IPeople類型:"); Console.WriteLine("============================================="); peopleClass = new PeopleClass(); Console.WriteLine("peopleClass是IPeople類型嗎?{0}", (peopleClass is IPeople).ToString());//False Console.WriteLine(); //peopleAbstractClass = null; //peopleClass = (PeopleClass)peopleAbstractClass;//因為抽象類PeopleAbstractClass和類PeopleClass之間沒有繼承關系,所以抽象類PeopleAbstractClass的實例peopleAbstractClass,無法使用類型轉換為類PeopleClass,編譯時會報錯 //peopleClass = peopleAbstractClass as PeopleClass;//因為抽象類PeopleAbstractClass和類PeopleClass之間沒有繼承關系,所以抽象類PeopleAbstractClass的實例peopleAbstractClass,無法使用as關鍵字轉換為類PeopleClass,編譯時會報錯 //peopleClass = null; //peopleAbstractClass = (PeopleAbstractClass)peopleClass;//因為抽象類PeopleAbstractClass和類PeopleClass之間沒有繼承關系,所以類PeopleClass的實例peopleClass,無法使用類型轉換為抽象類PeopleAbstractClass,編譯時會報錯 //peopleAbstractClass = peopleClass as PeopleAbstractClass;//因為抽象類PeopleAbstractClass和類PeopleClass之間沒有繼承關系,所以類PeopleClass的實例peopleClass,無法使用as關鍵字轉換為抽象類PeopleAbstractClass,編譯時會報錯 Console.WriteLine("============================================="); Console.WriteLine("peopleClass為null,peopleClass使用is關鍵字判斷是否為PeopleAbstractClass類型:"); Console.WriteLine("============================================="); peopleClass = null; Console.WriteLine("peopleClass是PeopleAbstractClass類型嗎?{0}", (peopleClass is PeopleAbstractClass).ToString());//False Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("peopleClass為PeopleClass類型的實例對象,peopleClass使用is關鍵字判斷是否為PeopleAbstractClass類型:"); Console.WriteLine("============================================="); peopleClass = new PeopleClass(); Console.WriteLine("peopleClass是PeopleAbstractClass類型嗎?{0}", (peopleClass is PeopleAbstractClass).ToString());//False Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("peopleAbstractClass為null,peopleAbstractClass使用is關鍵字判斷是否為PeopleClass類型:"); Console.WriteLine("============================================="); peopleAbstractClass = null; Console.WriteLine("peopleAbstractClass是PeopleClass類型嗎?{0}", (peopleAbstractClass is PeopleClass).ToString());//False Console.WriteLine(); Console.WriteLine("============================================="); Console.WriteLine("iPeople為null,peopleClass為null,peopleAbstractClass為null,使用is關鍵字判斷它們是否分別為IPeople、PeopleClass、PeopleAbstractClass類型:"); Console.WriteLine("============================================="); iPeople = null; peopleClass = null; peopleAbstractClass = null; Console.WriteLine("iPeople是IPeople類型嗎?{0}", (iPeople is IPeople).ToString());//False Console.WriteLine("peopleClass是PeopleClass類型嗎?{0}", (peopleClass is PeopleClass).ToString());//False Console.WriteLine("peopleAbstractClass是PeopleAbstractClass類型嗎?{0}", (peopleAbstractClass is PeopleAbstractClass).ToString());//False Console.WriteLine(); iPeople = (IPeople)null; iPeople = null as IPeople; peopleClass = (PeopleClass)null; peopleClass = null as PeopleClass; peopleAbstractClass = (PeopleAbstractClass)null; peopleAbstractClass = null as PeopleAbstractClass; Console.WriteLine("Press any key to end..."); Console.ReadKey(); } } }
該代碼詳細測試了接口與類、抽象類、結構體之間的相互轉換。