注意:我们定义接口成员,不需要为这个成员定义实现作用域。因为接口是纯粹的协议,如果我们定义实现,会产生编译错误。不过,.net接口还可以定义许多属性协议,我们更新上面接口如下:
接口除非被类或接口实现,否则接口没有什么用,接下来,我们将讲述一下接口的实现。
运行结果如下:
这种情况下,是没有问题的,但是如果一个类没有实现接口,调用Points属性的时候,就会出现编译错误。因此,有的时候就需要判断一个类型支持哪些接口,就用到了下面的方法:1、try-catch逻辑,接口强制转换中如果不支持这个接口,就会出现无效转换异常(InvalidCastException)。(不是最好的)2、获取接口引用:as关键字。例如新的类型A判断则可以如下:A a=new A();IPointy ips= a asIPointy ;//接下来判断ips是不是为空,然后输出其Points属性。3、获取接口引用:is关键字用法:if(a isIPointy){Console.Write((IPointy)a.Points);}else //...
结果:
执行结果:
出现如此错误的原因是因为我们的类不是实现名为GetEnumerator()的方法。将TheFather类进行如下更改,则编译安全通过:
在以前,如果我们希望构建支持foreach枚举的自定义集合,只能实现IEnumerable接口,可能还有IEnumerator接口,然而还可以通过迭代器来构建使用foreach循环的类型。1、用yield关键字构建迭代器方法。简单来说,迭代器就是这样一个成员方法,它制定了容器内部项被foreach处理时该如何返回。虽然迭代器方法还必须命名为GetEnumerator方法,返回值还必须是IEnumerator类型,但自定义类不需要实现原来那些接口了。修改TheFather类如下,将会实现和上述一样的功能,编译依旧可以安全通过:
yield关键字用来向调用方的foreach结构指定返回值。当到达yield return语句后,当前位置被存储下来,下次调用迭代器会从这个位置开始执行。2、构建命名迭代器更有趣的是,yield关键字从技术上说可以结合任何方法一起使用,无论方法名是什么。这就是命名迭代器技术。它的好处在于可以接受许多参数。注意,这些方法返回IEnumerable接口,而不是期望的IEnumerator兼容类型。修改TheFather类如下:
同时需要修改主函数内的迭代:
3、迭代器方法的内部表示如果C#编译器遇到迭代器方法,它就会在定义类型的作用域内动态生成嵌套类。记住,如果自定义类型要和C#的foreach关键字一起使用,容器就需要定义一个名为GetEnumerator的方法,它由IEnumerable接口类型来定制。通常,这个方法的实现只是交给保存子对象的内部成员,然而,我们也可以使用yield return语法来提供多个“命名迭代器”方法。
构建自定义类型的时候,可以实现IComparable以使得该类型数组可被排序,充实CompareTo的细节时候,需要决定排序操作的基准。修改代码如下:
下面是main函数的代码:
运行结果:
除此之外,我们还一颗指定多个排序顺序,以及自定义属性和自定义排序类型。在此不再陈述。
新闻热点
疑难解答