再談C#委託與事件

來源:互聯網
上載者:User

一、在控制台下使用委託和事件

我們都知道,C#中有“介面”這個概念,所謂的“介面”就是定義一套標準,然後由實作類別來具體實現其中的方法,所以說“介面,是一組類的抽象”。同 樣道理,我們可以將“委託”理解為“方法的抽象”,也就是說定義一個方法的模板,至於這個方法具體是怎麼樣的,就由方法自己去實現。

我們知道介面的最大好處就是可以實現多態,同理,“委託”是可以實現方法的多態,當我們想調用某個具體方法的時候,我們不直接調用這個方法,而是去調用這個委託。當然,我們必須在具體方法和委託之間建立某種關聯。

下面我們來看例子。

首先,我們定義一個委託:

public delegate void SaySomething(string name);

這跟抽象方法的文法格式很相似,只是多了一個關鍵字delegate。既然是對方法的一種抽象,那麼我們最關注的當然就是方法的傳回值以及方法的參 數了。所以上面紅色的部分就是我們定義出來的一個規矩,如果某個方法想委託我去做事,那麼請你遵循我的規矩,就是傳回值為void,參數為一個字串。我 們這個委託的含義是,當某個人來了,就向他說點東西。

好,既然我們已經定義了這個規矩,下面我們就定義具體的方法了。

public void SayHello(string name)
{
    Console.WriteLine("Hello," + name + "!");
}

public void SayNiceToMeetYou(string name)
{
    Console.WriteLine("Nice to meet you," + name + "!");
}

我們這裡一共定義了兩個方法,一個是向某人說Hello,另一個是向某人說Nice to meet you。我們看到,這裡定義的兩個方法的傳回值和參數跟我們前面定義的“委託”是一致的。

接下來,我們來看事件。

public event SaySomething come;

我們定義了一個事件,這個事件是“有人來了”,注意定義的時候我們使用event關鍵字,除此之外,我們還加上了前面定義的“委託”的名字。這個意 思是說,我這個事件只會跟“SaySomething”打交道,並且,當我這個事件發生的時候,我會通知關注我的這些“委託”(再由這些“委託”去調用具 體的方法)。

我們來定義一個測試方法:

public void test() { 
    SaySomething sayhello = new SaySomething(SayHello);
    SaySomething saynice = new SaySomething(SayNiceToMeetYou);
    come += sayhello;
    come += saynice;
    come("張三");
}

方法體中的前面兩行是用來執行個體化委託,注意我們用到了new關鍵字,就好像執行個體化一個類一樣,然後傳入一個參數,但這個參數不是string類型、也不是int類型,而是一個方法名。

再下面兩行就是將委託加到事件上,意思是說,如果你這個事件發生了,就告訴我一聲。可以通過“+=”來將n個委託執行個體加到某個事件上,一旦這個事件發生,所有的這些委託執行個體都會得到通知。

最後一行是觸發一個事件,注意我們是直接用一個事件名,然後跟一個參數,這又跟“委託”中定義的那個規矩一致(即,要有一個string類型的參數)。

最後運行一下

static void Main(string[] args)
{
    Program program = new Program();
    program.test();
    Console.Read();
}

我們回過頭來再看一下“事件”的定義:

public event SaySomething come;

這裡已經指出了“委託”的名字,所以,我們可以直接將方法加到事件上,而省略“委託”的執行個體化過程,因此上面的test()方法可以簡單寫為:

public void test() { 
    come += SayHello;
    come += SayNiceToMeetYou;
    come("張三");
}

 

二、在表單中使用委託和事件

上面的例子並不能體現委託和事件的優點,其實,委託和事件在C#中使用非常廣泛,例如,當我們點擊某個“按鈕”的時候,就會有一個“Click”事 件觸發,而這個事件會通知“委託”,在C#表單應用程式中,“委託”的名字比較規範,統一使用“EventHandler”,它的具體格式是“void EventHandler(object sender, EventArgs e);”。相信大家都寫過下面這樣子的HelloWorld程式:

當點擊按鈕的時候彈出一個對話方塊。我們怎樣實現的呢?你肯定會說,我們在設計視窗雙擊按鈕,就會自動為我們產生類似如下的方法:

private void button1_Click(object sender, EventArgs e)
{
    MessageBox.Show("我被點擊了!!!");
}

其實,這裡用到的就是事件和委託,這裡的button1_Click就是符合EventHandler委託規矩的一個具體的方法,即傳回值為void,參數分別是一個object和EventArgs。

我們可以在Form1.Designer.cs中看到如下代碼:

this.button1.Click += new System.EventHandler(this.button1_Click);

可以看到,這裡有一個Click事件,然後將一個委託執行個體附加到這個事件上,跟我們前面講的控制台應用程式中的用法是完全一樣的。那這個Click事件是怎麼觸發的呢?對於這些系統類別的事件,並不用我們管。

當然,我們也可以定義自己的事件和委託,例如我定義一個事件,這個事件就是輸出對象的名字。

我們這裡定義了一個ShowName委託和一個btnclick事件。並且,在button1_Click()方法中觸發這個btnclick事 件。最後的結果是,當我們點擊按鈕的時候,首先彈出一個“我被點擊了!!!”的對話方塊,然後確定之後再彈出另一個顯示按鈕名稱的對話方塊:

 轉自:

http://ruizhinet.blog.163.com/blog/static/9921382820092801032681/
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.