深入扩展方法

来源:互联网 发布:淘宝大学免费课程全套 编辑:程序博客网 时间:2024/06/03 21:14
  

Thomas Lebrun

Microsoft C# MVP

本文介绍了c#3.0中的一个新特性—扩展方法。

扩展方法使程序员无需通过继承或重编译原程序集等途径来向原有类型中增加新方法。甚至一些你可能都没有源程序的程序集中的类型也可以增加。比如“System.String”。

初看扩展方法

因为扩展方法可能难于理解。我们先来看看一个传统的示例。

看看下列简单的程序:

虽然上述程序可以正常运行,但代码还是不易阅读,因为其中调用了一个静态类中的静态方法。

使用扩展方法可以简化上述代码。来看看用扩展方法重写的相同应用:

如果运行重写的应用,你将看到相同的执行结果(输出大写信息),但上面的代码写起来更自然更易理解些。

在尝试理解扩展方法是如何实现前,我们先来看看通过Reflector反编译回来的IL代码:

如你所看到的,IL中的扩展方法调用已经被解释成了一个简单的静态方法调用。这意味着什么?扩展方法不过是种更简单调用静态方法的手段而已,使代码写起来更自然。

可以看到我们写的扩展方法在编译中被解释成了包含指定特性(ExtensionAttribute)的静态方法,该特性使编译器清楚该方法实际上是个扩展方法:

扩展方法在编译时会进行有效性的测试。编译时如果找不到扩展方法,你将收到类型下述的错误信息:

“’string’ does not contain a definition for ‘StringToUpper’ and no extension method‘StringToUpper’ accepting a first argument of type ‘string’ could be found”:

辩异扩展方法与其它方法

像我们前面看到的,扩展方法与其它实例方法一样使用.因此如何能够区分“扩展方法”与“正常方法”呢?嗯,Vs 2008在这方面可以帮助我们。

Vs2008中的Intellisense(智能感知)确实改善了开发者分辨方法类别的体验。因此,如果你使用“智能感知”显示当前对象所有可用方法与属性列表时,类似下图所示:

扩展方法通过如下辨别:

·        蓝色箭头

·        包含(extension)的提示信息

现在我们已经了解了扩展方法是如何工作的了,下面再来看看在我们的项目中如何正确使用这个新特性。

实现扩展方法:

为了理解扩展方法是如何实现的,我们再来回顾一下前面的例子:

扩展方法遵照如下规则定义:

·        扩展方法只能定义在非泛型,非嵌套静态类中。

·        扩展方法必须是静态方法。

·        扩展方法第一个参数前需包含操作符“this”.该参数称为“实例参数”,且实例参数必须为方法的第一个参数。

·        不允许其它操作符(ref, out, 等等…)与”this”同时出现。所以,值类型参数不能以引用方法传递给扩展方法。

·        实例参数不能是指针类型。

·        扩展方法可以声明为公共,内部,或私有之一:出于格式上的选择声明为公共方法,但是这不是必须的。

·        扩展方法需包含在一定范围的命名空间中。

如果你的方法符合上述规则,那你的方法就可以定义成扩展方法。

如果你的扩展方法与使用的地方不在同一命名空间下(甚至不在同一程序集中),你需要增加一行using语句导入相应命名空间中的相关内容,这样就可以使用其中的扩展方法了。

扩展方法与LINQ:

LINQ(集成查询语言)是一项面向对象,XML和SQL数据查询的新技术。其中使用了大量的扩展方法。如果你写过LINQ代码,可能你已经使用过这些未知类型的扩展方法。

上图中智能感知中列出的所有方法均在“System.Linq”命名空间下,在”System.Core.dll”程序集中。通过VS2008来看看System.Linq.Enumerable类的元数据:

原创粉丝点击