在迄今为止的内容中,每个方法都和声明它的类关联,扩展方法特性扩展了这个边界,允许编写的方法和声明它的类之外的类关联
class MyData { private double D1; private double D2; private double D3; public MyData(double d1,double d2,double d3) { D1 = d1;D2 = d2;D3 = d3; } public double Sum() { return D1 + D2 + D3; } }如上面的代码所示,这是一个有限的类,假设它还需要含有另一个方法,这个方法返回3个数据的平均值,则有这几种方法可以实现: (1)如果有源代码,只需要添加一个新方法即可 (2)如果不能修改这个类(如这个类在一个第三方类库中),那么只要它不是密封的,你就能把它用作一个基类在派生自它的类中实现这个额外的方法。 (3)如果不能访问代码,或者该类是密封的,就不得不在另一个类中使用该类的公有可用成员编写一个方法,例如可以编写一个下面这样的类,该类中方法接受MyData的实例作为参数来完成相应的需求。
static class ExtendMyData { public static double Average(MyData md) { return md.Sum() / 3; } } class Program { static void Main(string[] args) { MyData md = new MyData(3, 4, 5); Console.WriteLine(ExtendMyData.Average(md)); } }尽管这是非常好的解决方案,但如果能在类的实例自身上调用该方法会更优雅,也就是第二种调用方法。 ExtendMyData.Average(md); //静态调用形式 md.Average(); //实例调用形式
而扩展方法允许你使用第二种形式,通过对Average的声明做一个改动,就可以使用实例调用形式,做法就是在参数声明中的类型前增加关键字this,如下面所示,把this加到静态类的静态方法的第一个参数上,把该方法从类ExtendMyData的常规方法改变为类MyData的扩展方法,现在俩种调用形式都可以使用。
static class ExtendMyData { public static double Average(this MyData md) { return md.Sum() / 3; } public static double foo(this MyData md,int i) { return md.Sum()+i; } } class Program { static void Main(string[] args) { MyData md = new MyData(3, 4, 5); Console.WriteLine(ExtendMyData.Average(md)); //4 Console.WriteLine(md.Average()); //4 Console.WriteLine(md.foo(100)); //112 } }