当前位置: 首页 > 编程语言 > C# > 正文

c#3.0系列:Extension Method

时间:2010-12-19 gjcn

我们说在C#3.0中,引入了一些列新的特性,但是个人认为Extension Method 这个特性是最爽的,最有创新的。

它真正的解决了:在保持现有Type原封不动的情况下对其进行扩展,你可以 在对Type的定义不做任何变动的情况下,为之添加所需的方法成员。下面我就来 讲讲。

C#3.X出来之前

大家都知道javascript有个特新Prototype,它就如同C#3.X中的Extension Method。这里不多将了。

我们主要看看.NET的实现。在C#3.X出来之前我们可以做到对Type进行扩展。

interface的情况:

1public interface IEmployee
2{
3    string Name { get; set; }
4    int Age{get; set;}
5    int add(int n);
6}

对这个Interface进行扩展,为之添加一个Add方法执行相关的运算。我们唯 一的解决方案就是直接在这个Interface中添加一个Add成员。如上。实现了这个 Interface的Type必须实现该Interface的所有方法。所以,我们添加了Add这个 方法,将导致所有实现它的Type的重新定义和编译,在很多情况下,我们根本不 需要这样。

Class的情况:

如果我们将一个class作为基类,在基类中添加一个Add Method,所有的 Child Class都不会受到影响。但是在很多情况下,对于我们需要扩展的 Interface或者是class,我们是完全不能做任何改动。比如,我们要对datagrid 控件进行扩展。我们常用的方法就自定义一个Class去继承这个datagrid,将需 要添加的成员定义在我们自己定义的Class中,这就是我们常说的自定义控件, 如果对于一个Sealed Class又该如何呢?我们要求的是对这个不能变动的Type进 行扩展,也就是使这个不能变动的Type的Instance具有我们添加的对象。

如果听到这样的要求:我们要对一个Type或者Interface进行扩展,却不允许 我们修改它。这个要求确实有点苛刻。但是c#3.x 中我们可以选择Extension Method。Extension Method本质上是在被扩展的对象实例上可以调用的静态函数 ,不是继承,所以不同于普通的成员函数,扩展函数不能直接访问被扩展对象的 成员。只能通过该对象的实例来访问。

C#3.X出来之后

简单地说Extension Method是一个定义在Static Class的一个特殊的Static  Method。之所以说这个Static Method特别,是因为Extension Method不但能 按照Static Method的语法进行调用,还能按照Instance Method的语法进行调用 。

我们还是先来看例子:

public static class MyExtensionMethods
   {
     // this代表扩展方法应用于string类型上
     public static int ToInt32(this string s)
     {
       int i;
       Int32.TryParse(s, out i);
       return i;
     }
   }
public static void fnExtensionMethod()
     {
       string s = "27";
       // 使用string的ToInt32()扩展方法
       int i = s.ToInt32();
     }

我们可以看看上面的例子,我们知道net framework 里string是个Sealed 类 型,我们只能使用Extension Method来对其进行扩展。我们可以看看它的定义方 式。ToInt32是一个Static方法。和一般的Static方法不同的是:在第一个参数 前添加了一个this 关键字。这是在C# 3.0中定义Extension Method而引入的关 键字。添加了这样一个关键字就意味着在调用该方法的时候这个标记有this的参 数可以前置,从而允许我们向调用一般Instance Method的方式来调用这个 Static Method。注意:需要在(只需要在)第一个参数前面使用this修饰。