在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(); } } }
该代码详细测试了接口与类、抽象类、结构体之间的相互转换。