在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);
}