1. 程式人生 > >c#神奇的擴充套件方法

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