科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件理解C# 3.0新特性之Extension方法浅议

理解C# 3.0新特性之Extension方法浅议

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

C# 3.0新特性的Extension method可以在保持现有Type原封不动的情况下对其进行扩展,你可以在对Type的定义不做任何变动的情况下,为之添加所需的方法成员。在这篇文章中,我将介绍我自己对Extension method这个新特性的理解。

作者:Artech 来源:博客园 2007年8月23日

关键字: C#

  • 评论
  • 分享微博
  • 分享邮件

在C# 3.0中,引入了一些列新的特性,比如:Implicitly typed local variable, Extension method,Lambda expression, Object initializer, Anonymous type, Implicitly typed array, Query expression, Expression tree。个人觉得在这一系列新特性的,最具创新意义的还是Extension method,它从根本上解决了这样的问题:在保持现有Type原封不动的情况下对其进行扩展,你可以在对Type的定义不做任何变动的情况下,为之添加所需的方法成员。在这篇文章中,我将介绍我自己对Extension method这个新特性的理解。

一、Prototype in JavaScript

为了说明Extension method到底是为了解决怎样的问题,我首先给出一个类似的、大家都比较熟悉的应用:JavaScript 中的Prototype。

比如我们在JS通过function定义了一个Vector class,代表一个2维向量。

function Vector (x,y)

{

 this.x = x;

 this.y = y;

}

现在我们需要在不改变Vector定义的前提下,为之添加相关的进行向量运算的Method。比如我们现在需要添加一个进行两个向量相加运算的adds方法。在JS中,我们很容易通过Prototype实现这一功能:

Vector.prototype.adds = function(v)

{

 if(v instanceof Vector)

 {

return new Vector(this.x+v.x, this.y + v.y);

 }

 else

 {

alert("Invalid Vector object!");

 }

}

那么,通过添加上面的一段代码,我们完全可以把adds方法作为Vector的一个方法成员。现在我们可以这样的方式来写代码:

var v = new Vector (1,2);

v= v.adds(v);

alert("x = " +v.x + ", y = "+v.y);

Extension Method之于C# 3.0就如同Prototype之于JavaScript。

二、如何在C# 2.0中解决Type的扩展性

我们一个完全一样的问题从弱类型、解释型的编程语言JavaScript迁移到C#这种强类型、编译型的语言上来。我们先看看在不能借助Extension Method这一新特性的C# 2.0中,我们是如何解决这一问题。

我们先来看看如何对一个Interface进行扩张。假设我们有如下的一个IVector interface的定义:

public interface IVector

{

 double X { get; set; }

 double Y { get; set; }

}

我们希望的是如何对这个Interface进行扩展,为之添加一个Adds Method执行向量相加的运算。我们唯一的解决方案就是直接在这个Interface中添加一个Adds成员:

public interface IVector

{

 double X { get; set; }

 double Y { get; set; }

 IVector Adds(IVector vector);

}

由于Interface和实现它的Type的紧密联系:所以实现了某个Interface的Type必须实现该Interface的所有方法。所以,我们添加了Adds Method,将导致所有实现它的Type的重新定义和编译,在很多情况下,这种代价我们是负担不起的:比如在系统的后期维护阶段,对系统的进行局部和全部的重新编译,将很有可以导致一个正常运行的系统崩溃。Interface的这种局限性在面向抽象设计和编程中应该得到充分的考虑,这也是我们在很多情况下宁愿使用Abstract Class的一个主要原因。

上面说到了对Interface的扩展,会出现必须实现Interface的Type进行改动的风险。我想有人会说,对Class尽心扩展就不会出现这样的情况了吧。不错,Class的继承性确保我们在Parent class添加的Public/Protect能被Child Class继承。比如:如果Vector是一个Super Class:

public class Vector

{

 private double _x;

 private double _y;

 public double X

 {

get {return this._x;}

set { this._x = value;}

 }

 public double Y

 {

get { return this._y;}

set {this._y = value;}

 }

}

如果我们在Vector Class中添加一个Adds Method,所有的Child Class都不会受到影响。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章