欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

簡單聊聊c# 事件

 更新時間:2020年07月23日 10:29:46   作者:Learning hard  
這篇文章主要介紹了c# 事件的相關資料,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下

引言:

前面幾個專題對委托進行了詳細的介紹的,然后我們在編寫代碼過程中經常會聽到“事件”這個概念的,尤其是寫UI的時候,當我們點擊一個按鈕后VS就會自動幫我們生成一些后臺的代碼,然后我們就只需要在Click方法里面寫代碼就可以,所以可能有些剛接觸C#的朋友就覺得這樣很理所當然的,也沒有去思考這是為什么的,為什么點擊下事件就會觸發(fā)我們在Click方法里面寫的代碼呢?事件到底扮演個什么樣的角色呢?為了解除大家的這些疑惑,下面就詳細介紹了事件,讓一些初學者深入理解C#中的事件的概念。

一、為什么C#中會有事件的?

  前面專題中介紹了我理解的為什么需要委托的,所以這里我來分享下我理解的為什么C#中要引入事件這個概念的。下面就簡單講講生活中事件的例子的,最近我生日剛過完的,我就以生日這個話題要談談的,日子一天天的過去,當生日的日期到的時候,這時候就觸發(fā)了生日事件的,此時過生日的人就是觸發(fā)生日事件的對象的,然后有些關系你的朋友就會對這個事件進行關注,一旦這個事件觸發(fā), 他們就可能會陪你一起慶祝生日,然后送禮物給你,當然并不是所有人都會對你的生日關注的,有些人肯定根本就不知道的, 只有對于你生日事件進行了關注了的人才會送禮物給你。這樣的生活中的一個生日過程,然而對于為什么C#中會有事件這個概念當然就更好理解了,C#是一個面向對象的語言,我們使用C#語言進行編碼也是為了用代碼幫助我們完成現(xiàn)實生活中的事情的,所以當然也就必須有事件來反映生活中發(fā)生事情的情況了。

二、自己如何實現(xiàn)一個事件模式的?

  現(xiàn)在我們知道了為什么C#要引入事件了,但是對于我們在代碼中使用的事件大部分都是.net類庫為我們提供的,例如控件的各種事件,我們只需要點擊按鈕后就會觸發(fā)點擊事件的,但是我們很想理解這個事件是如何觸發(fā)的,我們是否可以自己定義實現(xiàn)事件模式的一個程序的呢?答案當然是可以的,下面就以上面生日的例子來通過代碼來解釋下如何實現(xiàn)一個事件模式的。

具體代碼為:

using System;
using System.Threading;

namespace BirthdayEventDemo
{
  class Program
  {
    static void Main(string[] args)
    {
      // 實例化一個事件源對象
      Me eventSource = new Me("Learning Hard");

      // 實例化關注事件的對象
      Friend1 obj1 = new Friend1();
      Friend2 obj2 = new Friend2();

      // 使用委托把對象及其方法注冊到事件中
      eventSource.BirthDayEvent+=new BirthDayEventHandle(obj1.SendGift);
      eventSource.BirthDayEvent+=new BirthDayEventHandle(obj2.Buycake);
      
      // 事件到了觸發(fā)生日事件,事件的調用
      eventSource.TimeUp();
      Console.Read();
    }
  }
  // 第一步: 定義一個類型用來保存所有需要發(fā)送給事件接收者的附加信息
  public class BirthdayEventArgs : EventArgs
  {
    // 表示過生日人的姓名
    private readonly string name;

    public string Name
    {
      get { return name;}
    }

    public BirthdayEventArgs(string name)
    {
      this.name = name;
    }
  }
  // 第二步:定義一個生日事件,首先需要定義一個委托類型,用于指定事件觸發(fā)時被調用的方法類型
  public delegate void BirthDayEventHandle(object sender, BirthdayEventArgs e);
  // 定義事件成員
  public class Subject
  {
    // 定義生日事件
    public event BirthDayEventHandle BirthDayEvent;

    // 第三步:定義一個負責引發(fā)事件的方法,它通知已關注的對象(通知我的好友)
    protected virtual void Notify(BirthdayEventArgs e)
    {
      // 出于線程安全的考慮,現(xiàn)在將對委托字段的引用復制到一個臨時字段中
      BirthDayEventHandle temp = Interlocked.CompareExchange(ref BirthDayEvent, null, null);
      if (temp != null)
      {
        // 觸發(fā)事件,與方法的使用方式相同
        // 事件通知委托對象,委托對象調用封裝的方法
        temp(this, e);
      }
    }
  }

  // 定義觸發(fā)事件的對象,事件源
  public class Me : Subject
  {
    private string name;
    public Me(string name)
    {
      this.name = name;
    }
    public void TimeUp()
    {
      BirthdayEventArgs eventarg = new BirthdayEventArgs(name);
      // 生日到了,通知朋友們
      this.Notify(eventarg);

    }
  }

  // 好友對象
  public class Friend1
  {
    public void SendGift(object sender,BirthdayEventArgs e)
    {
      Console.WriteLine(e.Name+" 生日到了,我要送禮物");
    }
  }
  public class Friend2
  {
    public void Buycake(object sender, BirthdayEventArgs e)
    {
      Console.WriteLine(e.Name + " 生日到了,我要準備買蛋糕");
    }
  }
}

運行結果為:

三、編譯器是如何解釋事件的呢?

  上面我們已經介紹了如何去實現(xiàn)自己去實現(xiàn)一個事件模式的,大家可以展開代碼來具體的查看的,實現(xiàn)過程主要是——定義觸發(fā)對象的事件源(指的是誰過生日)->定義關注你生日事件的朋友對象-> 方法登記對事件的關注,當事件觸發(fā)時通知登記的方法被調用。然而相信大家還有有疑問——到底C#中的事件是什么呢?編譯器又是如何去解釋它的?下面就為大家解除下疑惑的:

  首先事件其實就是委托的(確切的說事件就是委托鏈),從上面的代碼中,我們定義的事件除了使用event關鍵字外,還用到了一個委托類型,然而委托是一個類,類肯定就有屬性字段的,然而我們就可以把事件理解為委托的一個屬性,屬性的返回值是一個委托類型。說事件是委托的一個屬性,是有根據的,我們通過中間語言代碼可以知道編譯器是如何去解釋我們定義的事件的。

 // 第二步:定義一個生日事件,首先需要定義一個委托類型,用于指定事件觸發(fā)時被調用的方法類型
  public delegate void BirthDayEventHandle(object sender, BirthdayEventArgs e);
  // 定義生日事件
    public event BirthDayEventHandle BirthDayEvent;

當我們像上面定義一個事件時,編譯器會把它轉換為3段代碼(大家可以通過IL反匯編程序來查看的):

// 1. 一個被初始化為null的私有委托字段
    private BirthDayEventHandle BirthDayEvent =null;

    //2. 一個公共add_BirthDayEvent方法
    public void add_BirthDayEvent(BirthDayEventHandle value)
    {
      // 以一種線程安全的方式從事件中添加一個委托
    }
    // 3. 一個公共的remove_BirthDayEvent方法
    public void remove_BirthDayEvent(BirthDayEventHandle value)
    {
      // 以一種線程安全的方式從事件中移除一個委托
    }

第一段代碼一個委托的私有字段,該字段是對一個委托列表的頭部的引用,事件發(fā)生時會通知這個列表中的委托。字段初始化為null,表明無關注人登記了對事件的關注。
第二段代碼是一個以add為前綴的方法,該方法是由編譯器自動命名的,代碼內容調用Delegate.Combine方法將委托實例添加到委托列表中,返回新的列表地址,并將這個地址存回字段。

第三段代碼也是一個方法,它使得一個對象注銷對事件的關注,同樣的方法體調用Delegate.Remove方法將委托實例從委托列表中刪除,返回新的列表地址,并將這個地址存回字段中。(注,如果試圖刪除一個從未添加過的方法,Delegate.Remove方法在內部將不做任何事情,也就是說,不會拋出任何一次,也不會顯示任何警告,事件的方法集合保持不變)。

同時大家也可以通過調試來說明事件是一個委托鏈的,大家可以在 eventSource.BirthDayEvent+=new BirthDayEventHandle(obj2.Buycake);這行代碼設置一個斷點調試的,下面是我調試過程中的一個截圖,大家也可以自己調試看看的,這樣將會更加理解事件是一個委托鏈的概念:

按F10運行一行后的截圖

通過上面的截圖,相信大家對于事件是一個委托鏈的概念相信會有進一步的理解的。

四、小結

  到這里本專題的內容也就介紹完了, 希望通過本專題,大家可以對事件有進一步的理解,理解事件與委托之間的關系。這個專題通過自己實現(xiàn)的一個事件模式里解釋事件的本質,然而我們經常使用的是Net類庫中定義好的事件,然而有些剛接觸C#的人卻不理解Net中定義的事件背后所做的事情,只是知道點下按鈕后在Click方法里面寫入自己的一些控制代碼,然而背后的過程具體是怎樣的,既然事件是委托,那么Click事件是委托類型,其中的委托類型又是怎么被實例化的呢?這些內容將在下一個專題給大家分享下的。

以上就是簡單聊聊c# 事件的詳細內容,更多關于c# 事件的資料請關注腳本之家其它相關文章!

相關文章

  • C#實現(xiàn)對二維數組排序的方法

    C#實現(xiàn)對二維數組排序的方法

    這篇文章主要介紹了C#實現(xiàn)對二維數組排序的方法,實例分析了C#數組遍歷與排序的相關技巧,需要的朋友可以參考下
    2015-06-06
  • C#采用Winform實現(xiàn)類似Android的Listener

    C#采用Winform實現(xiàn)類似Android的Listener

    這篇文章主要介紹了C#采用Winform實現(xiàn)類似Android的Listener,很實用的技巧,需要的朋友可以參考下
    2014-08-08
  • C#實現(xiàn)SMTP服務發(fā)送郵件的示例代碼

    C#實現(xiàn)SMTP服務發(fā)送郵件的示例代碼

    這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)SMTP服務發(fā)送郵件的功能,文中的示例代碼講解詳細,對我們學習C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-12-12
  • C#中的隨機數函數Random()

    C#中的隨機數函數Random()

    這篇文章介紹了C#生成隨機數的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • C#讀取與寫入txt文件內容的實現(xiàn)方法

    C#讀取與寫入txt文件內容的實現(xiàn)方法

    在 C# 中讀取和寫入文本文件內容是一個常見的任務,本文主要介紹了使用幾種不同方法讀取和寫入文本文件的示例,并通過代碼示例介紹的非常詳細,具有一定的參考價值,需要的朋友可以參考下
    2024-08-08
  • Unity實現(xiàn)已知落點和速度自動計算發(fā)射角度

    Unity實現(xiàn)已知落點和速度自動計算發(fā)射角度

    這篇文章主要為大家詳細介紹了Unity實現(xiàn)已知落點和速度自動計算發(fā)射角度,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • c#異步task示例分享(異步操作)

    c#異步task示例分享(異步操作)

    這篇文章主要介紹了c#異步task示例(異步操作),需要的朋友可以參考下
    2014-03-03
  • 在C#中使用MSMQ的方法

    在C#中使用MSMQ的方法

    這篇文章主要介紹了在C#中使用MSMQ的方法,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-01-01
  • C# 9 新特性之增強的foreach詳解

    C# 9 新特性之增強的foreach詳解

    這篇文章主要介紹了C# 9 新特性之增強的foreach的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • C#設置子窗體在主窗體中居中顯示解決方案

    C#設置子窗體在主窗體中居中顯示解決方案

    接下來將介紹C#如何設置子窗體在主窗體中居中顯示,本文提供詳細的操作步驟,需要的朋友可以參考下
    2012-12-12

最新評論