c#神奇的擴展方法

以前總聽說擴展方法擴展方法,只是聽說是c#3.0後出來的新玩意,也僅僅是知道linq中用到好多的擴展方法,但是他究竟是個什麼東東,怎麼用它,用它的好處是什麼,總是模模糊糊,那麼我們今天就嘗試揭開它神祕的面紗。

  我們現在看到每個方法都和聲明它的類關聯,但是c#3.0的擴展方法的特性擴展了這個邊界,允許編寫和聲明它的類之外的類關聯的方法。想要知道如何利用這個特徵,我們先看一個例子:

class mydata
{
    double d1,d2,d3;
    public mydata(double d1,double d2,double d3)
    {
        d1=d1;d2=d2;d3=d3;
    }
    public double sum()
    {
        return d1+d2+d3;
    }
}

   這是一個非常簡單而且功能有限,但假設它含有另外一個方法會更有用,該方法返回三個數據的平均值.那麼我們有幾種方法可以實現這個增加的功能.

  • 如果我們有源代碼,那麼我們可以直接修改這個類,將方法直接添加進去.
  • 然而,如果我們不能修改這個類,例如,如果這個類在一個第三方的類庫中,那麼只要它不是密封的,那麼我們可以把它當作基類並在派生類中實現這個新增的方法.

  如果我們不能訪問代碼,或該類是密封的,或有其它設計原因使這些方法不能工作,那麼我們不得不在另外一個類中使用該類的公有可用成員編寫一個方法.

例如,我們可以編寫一個下面代碼中這樣的類:

 

此文來自: 馬開東博客 轉載請註明出處 網址: http://www.makaidong.com

身調用該方法,而不是創建一個作用於它的類的實例,它將會更優雅。下面兩行代碼闡明瞭它們的區別。第一行使用剛展示的方法:在另一個類的實例上調用靜態方法。第二行展示了我們願意使用的形式:在對象自身上調用實例犯非法。

 

extendmydata.average(md);//在一個類的實例上調用靜態方法
   md.average();           //在對象自身上調用實例方法

 

擴展方法允許你使用第二種形式,即使第一種形式可能是編寫這種調用的正確方法。通過對方法average的聲明做一個小小的改動,就可以實現實例調用方式。需要修改的是在參數生命中的類型名稱前增加關鍵字this,如下面所示。把this關鍵字加到靜態類的靜態方法的第一個參數上,把該方法從extendmydata的正規方法改變爲類mydata的擴展方法。現在兩種調用方式都可以使用:

static class extendmydata
{
    public static double average(this mydata md)
      {
      }
}

擴展方法重要的需求如下:

  • 聲明擴展方法的類必須聲明爲static.
  • 擴展方法本身必須聲明爲static.
  • 擴展方法必須包含關鍵字this作爲它的第一個參數類型,並在後面跟着它所擴展類的名稱。

另外需要注意的是:c#只支持擴展方法,不支持擴展屬性、擴展事件等。

下面代碼展示了展示了一個完整的程序,注意方法average完全如同它是mydata的實例成員那樣被調用!

using system;
using system.collections.generic;

public class myclass
{
    public static void main()
    {
      mydata md=new mydata(1,2,3);
      console.writeline("sum:{0}",md.sum());
      console.writeline("average:{0}",md.average());
    }
}
class mydata
{
    double d1,d2,d3;
    public mydata(double d1,double d2,double d3)
    {
        d1=d1;d2=d2;d3=d3;
    }
    public double sum()
    {
        return d1+d2+d3;
    }
}
static class extendmydata
{
    public static double average(this mydata md)
    {
        return md.sum()/3;
    }
}

爲了方便大家理解,我又增加了一個例子。分別爲string 和集合做擴展方法:

using system;
using system.collections.generic;
using system.collections;
using extend;//擴展方法的命名空間
namespace mytest
{
public class myclass
{
    public static void main()
    {
      string str = "{0}先生。".with("幕三少");
      console.writeline("您好!:"+str);
       //調用集合的擴展方法
       str.showitems<char>();
      console.read();
    }
}
}
namespace extend
{
    static class extendmydata
{
    public static string with(this string content,params string[] args)
    {
        return string.format(content,args);
    }
    //爲集合做擴展方法
    public static void showitems<t>(this ienumerable<t> items)
    {
         foreach (var item in items)
            {
                console.writeline(item);
            }
    }
}
}

 


搜索此文相關文章:C#神奇的擴展方法此文鏈接:http://www.makaidong.com/IT%E5%8D%9A%E5%AE%A2%E5%9B%AD/35773.shtml

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章