令人激动的“扩展”
2. 如何实现扩展方法
下面我们就来看一看C#3.0中扩展方法是如何实现的。
static class Program
{
static void Main(string[] args)
{
//这里的Game命名空间定义在第三方的类库中
Game.ForzenSword sword = new ForzenSword();
sword.AutoCooling(5);
}
//参数中的this指明是哪一个类的扩展方法
static void AutoCooling(this ForzenSword sword, int seconds)
{
Console.WriteLine(string.Format("ForzenSword will cool down in {0} seconds", seconds));
}
}
这里我们可以看到,首先把我们要扩展的方法定义到一个静态类中,这里为了演示方便,我把它定义在了static class Program即我们的Main函数所在的类中;然后我们定义这个方法的第一个参数为类型的实例,并在其前面加上‘this’表示这是扩展到FrozenSword类型中的方法,这样我们就成功扩展了FrozenSword 类型, 大家可以看到我在Main函数中对该方法的调用,是不是很简单呢:)
3. 扩展方法会带来的问题
当我们大家在惊叹扩展方法给我们带来的灵活性的时候,我们也有一丝疑问,这样会不会破坏原有程序集的封装性呢?答案当然是否定的,但是确实会造成效能上的一些问题和隐患。我们看下面一个例子:
namespace System
{
public static class BadClass
{
public static void DoSomethingEvil(this object s)
{
//对s做点坏事...
}
}
}
因为几乎所有的C#代码都会引用到System这个命名空间,而我们定义的这个方法又是对object类型的扩展,所以我们几乎可以认为这个扩展方法被定义成了一个全局的函数!这就让我们思考它的效能问题,上面的例子运行的实际效果将会使每一个引用类型都加载DoSomethingEvil这个方法(因为C#里引用类型都是object类的子类),这是相当大的资源消耗!当然我们也有解决的办法,最经典的莫过于System.Xml.Linq和System.Data.Linq,LINQ也是C#3.0的一个重要特性,不熟悉的读者可以参考msdn相关文章,LINQ将对Xml文档的扩展方法包和对数据库的扩展方法包分开,使得我们可以有选择的加载,这样可以大大减少我们加载的扩展方法的数量。实际上我们自己在定义扩展方法时也应该分门别类的组织起来,而不应该定义在同一个namespace中加大系统加载的负担。
0
相关文章
static class Program