溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C#之事件的詳細(xì)解析

發(fā)布時(shí)間:2020-07-18 14:58:06 來源:億速云 閱讀:143 作者:小豬 欄目:編程語言

這篇文章主要講解了C#之事件的詳細(xì)解析,內(nèi)容清晰明了,對(duì)此有興趣的小伙伴可以學(xué)習(xí)一下,相信大家閱讀完之后會(huì)有幫助。

事件:定義了事件成員的類允許通知其他其他對(duì)象發(fā)生了特定的事情。具體的說,定義了事件成員的類能提供以下功能

1.方法能登記它對(duì)事件的關(guān)注

2.方法能注銷它對(duì)事件的關(guān)注

3.事件發(fā)生時(shí),登記了的方法將收到通知

類型之所以能提供事件通知功能,是因?yàn)轭愋途S護(hù)了一個(gè)已登記方法的列表。事件發(fā)生后,類型將通知列表中所有已登記的方法。

事件是以委托為基礎(chǔ)。委托是調(diào)用回調(diào)方法的一種類型安全的方式。對(duì)象憑借回調(diào)方法接收他們訂閱的通知。

假如有一下場景:要設(shè)計(jì)一個(gè)電子郵件程序。當(dāng)有新的郵件的到達(dá)時(shí),用戶希望做些一別的操作,例如轉(zhuǎn)發(fā)給其他人或其他想實(shí)現(xiàn)的功能。事件在其中起到的就是一個(gè)通知的作用,告訴其他對(duì)象有新的郵件到達(dá)了,可以做XXX事情了。

下面使用事件實(shí)現(xiàn)這個(gè)功能

1.定義一個(gè)附加信息類,用來通知接收者發(fā)生了什么。

/// <summary>
  /// 事件附加消息
  /// </summary>
  public class NewMailEventArgs:EventArgs{
    private readonly string m_from,m_to,m_subject;
    public NewMailEventArgs(string from,string to,string subject){
      m_from=from;
      m_to=to;
      m_subject=subject;
    }
    // 發(fā)件人
    public string From { get{return m_from;} }
    // 接收人
    public string To { get{return m_to;} }
    // 主題
    public string Subject{get{return m_subject;}}
  }

附加信息類繼承了EventArgs,這個(gè)基類只定義了一個(gè)空的信息,在沒有附加信息時(shí)可直接使用EventArgs.Empty。EventArgs類的源代碼

namespace System
{
  //
  // Summary:
  //   Represents the base class for classes that contain event data, and provides a
  //   value to use for events that do not include event data.
  public class EventArgs
  {
    //
    // Summary:
    //   Provides a value to use with events that do not have event data.
    public static readonly EventArgs Empty;

    //
    // Summary:
    //   Initializes a new instance of the System.EventArgs class.
    public EventArgs();
  }
}

2.定義事件成員

事件成員使用C#關(guān)鍵字event定義。每個(gè)事件成員都要指定以下內(nèi)容:可訪問標(biāo)識(shí)符public(因?yàn)橹挥衟ubli才能使其他對(duì)象訪問),委托類型以及名稱。

 public class MailManager{
    // 定義事件成員
    public event EventHandler<NewMailEventArgs> NewMail;
    
  }

它的類型是EventHandler<NewMailEventArgs> 這意味著事件通知的所有接收者都必須有一個(gè)和這個(gè)類型匹配的回調(diào)方法。System.EventHandler的委托定義類型如下:

namespace System
{
  //
  // Summary:
  //   Represents the method that will handle an event when the event provides data.
  //
  // Parameters:
  //  sender:
  //   The source of the event.
  //
  //  e:
  //   An object that contains the event data.
  //
  // Type parameters:
  //  TEventArgs:
  //   The type of the event data generated by the event.
  public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
}

所以接收者必須提供的方法必須是一下形式:

void MethodName(Object sender,NewMailEventArgs e);

3. 定義負(fù)責(zé)引發(fā)事件的方法來通知事件的登記對(duì)象

public class MailManager{
    // 定義事件成員
    public event EventHandler<NewMailEventArgs> NewMail;
    // 定義負(fù)責(zé)引發(fā)事件的方法來通知已登記的對(duì)象
    protected virtual void OnNewMail(NewMailEventArgs e){
      // 將字段復(fù)制到一個(gè)臨時(shí)變量,避免多線程情況中這個(gè)成員被移除
      EventHandler<NewMailEventArgs> temp=Volatile.Read(ref NewMail);
      if(temp!=null) temp(this,e);
    }

    // 接受附加信息并調(diào)用引發(fā)事件的方法來通知所有登記的對(duì)象
    public void SimulateNewMail(string from,string to,string subject){
      NewMailEventArgs e=new NewMailEventArgs(from,to,subject);
      OnNewMail(e);
    }
  }

4. 定義事件接收者

public class Fax{
    public Fax(MailManager mm){
      // 構(gòu)造委托實(shí)例,向事件登記回調(diào)方法
      mm.NewMail+=FaxMsg;
    }
    /// <summary>
    /// 回調(diào)方法
    /// </summary>
    /// <param name="sender">表示MailManager對(duì)象,便于將信息傳遞給他</param>
    /// <param name="e">表示MailManager對(duì)象想傳給我們的附加信息</param>
    private void FaxMsg(object sender,NewMailEventArgs e){
      Console.WriteLine("msg:{0},{1},{2}",e.From,e.To,e.Subject);
    }

    /// <summary>
    /// 注銷對(duì)事件的登記
    /// </summary>
    /// <param name="mm"></param>
    public void Unregister(MailManager mm){
      mm.NewMail-=FaxMsg;
    }
  }

對(duì)象不在接收事件通知時(shí)應(yīng)注銷對(duì)事件的關(guān)注。因?yàn)閷?duì)象只要向事件等急了它的一個(gè)方法,便不能被垃圾回收。

5. 程序初始化時(shí)應(yīng)首先構(gòu)造MailManager對(duì)象,將指向它的變量傳遞給Fax。在Fax構(gòu)造器中添加對(duì)事件的關(guān)注。最后調(diào)用MailManager對(duì)象的事件通知方法

static void Main(string[] args)
    {
      MailManager mm=new MailManager();
      Fax f=new Fax(mm);
      mm.SimulateNewMail("a","b","Hello World!");
      Console.ReadKey();
    }

控制臺(tái)輸出結(jié)果:以調(diào)用回調(diào)方法。

C#之事件的詳細(xì)解析

看完上述內(nèi)容,是不是對(duì)C#之事件的詳細(xì)解析有進(jìn)一步的了解,如果還想學(xué)習(xí)更多內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI