3.4 扩展方法
C#语言从3.0开始增加了一个很特别的功能——扩展方法,扩展方法类似于一个补丁,在不能够继承的类中添加一个需要的方法或为已经存在的类增加自定义的方法。在C#4.0中如果要将查询功能添加到现有的System.Collections.IEnumerable和System.Collections. Generic.IEnumerable<T>类型的INQ标准查询运算符中时,首先将其引入到using System.Linq指令的范围,然后添加自定义的扩展方法,之后任何实现了IEnumerable<T>类型方法的实现都具有GroupBy、OrderBy、Average等实例的方法。
3.4.1 定义扩展方法
要定义扩展方法,首先要知道定义方法的几点规则。
(1)方法所在的类必须是静态的(私有公共都可以)。
(2)方法也必须是静态的(私有公共都可以)。
(3)第一个函数参数前带this(必须是第一参数前)。
(4)方法的第一个参数必须是要扩展的那个类型,如要给int扩展一个方法,那么,第一个参数就必须是int。
下面代码演示了为系统的string类定义了一个扩展方法IsLeft,如果输入left为真,其他返回假。
具体调用方法如下。
输出结果如图3-12所示。
图3-12 自定义扩展方法
在引入扩展方法后,新的编译器会将扩展方法完全自动地加入到程序集中,这样用户就可以随意调用自己的扩展方法,而不用修改任何原来的代码,也不用继承任何系统的类来完成想要的操作。
3.4.2 调用扩展方法
调用扩展方法与调用静态方法相同,可以通过两种方式调用:一种是用实例方法调用,另一种是用静态方法直接调用。下面代码显示了一个扩展方法。
上述代码中定义了一个扩展方法,扩展方法加在string类中,如果输入的字符串为left时返回真,这里处理了大小写,其他情况全部返回假。
下面代码演示了调用方式。
方法执行结果如图3-13所示。
图3-13 调用自定义扩展方法
3.4.3 扩展方法的使用范围
在扩展方法的使用范围有以下限制。
(1)如果它们属于不同的命名空间,那么在使用时要先引用扩展方法所在的命名空间。
(2)扩展方法不能与被扩展类中其他方法的名称重复,但是不代表扩展方法不能重载,只是不能同已经命名了的方法相同。在命名为相同的方法时,将不会被调用,系统会自动调用原有的方法,忽略自己写的方法。
(3)由于扩展方法是静态方法,所以,必须要符合静态方法的所有限制。
下面通过代码演示具体的使用。
在上面的代码中演示了方法的重复问题,这里命名一个ToString系统的方法,在调用这个方法后,程序返回一个Hello Word的字符串,下面调用具体的方法,看看是否能返回,代码如下。
上面代码的运行结果如图3-14所示。
图3-14 扩展方法的使用结果
这里运行的结果还是原来赋值的结果,并没有返回重写的结果,说明系统忽略了重新扩展的方法。
3.4.4 使用扩展方法扩展接口类型
用户不但能使用扩展方法为类添加方法,还能为接口扩展方法。用代码说明接口扩展的方法。代码如下。
具体调用方法,首先命名了一个测试时使用的对象,然后为这个对象分配一个空间,再调用对象的方法和扩展方法,最后输出结果,调用代码如下。
输出结果如图3-15所示。
图3-15 调用扩展方法的结果
该例中添加了一个扩展方法,在扩展方法中返回一个字符串。在另外的方法中返回不同的字符串,来说明接口扩展方法。