C#語法學習事件(Event)

/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2008/9/2
 * Time: 下午 11:39
 * 事件(event)
 * 
 * 事件是類在發生其關注的事情時用來提供通知的一种方式.
 * 例如,封裝用戶界面控件的類可以定義一個在用戶單擊該控件時發生的事件.
 * 控件類不關心單擊按鈕時發生了什麼,但它需要告知派生類單擊事件已發生.
 * 然後,派生類可選擇如何響應.
 * 
 * 事件有兩個角色
 * 事件發行者(Publisher):
 * 一個事件發行者,也稱作發送者(sender),其實就是一個對像.
 * 這個對像會自行維掮本身的狀態信息.
 * 當本身狀態信息變動時,便觸發一個事件,並通知所有的事件訂閱者.
 * 事件訂閱者(Subscriber):
 * 對事件感興趣的對像,也稱為接收者(Receiver),可以註冊感興趣的事件.
 * 通常需提供一個事件處理程序,在事件發行者觸發一個事件後,
 * 會自動執行這段代碼的內容.
 * 
 * 
 
*/
 
using System;
 
class Publisher//出版社
 {
     
public delegate void Publish();//聲明事件所需的代理
     public event Publish OnPublish;//事件的聲明
     public void issue()//觸發事件的方法
     {
         
if(OnPublish!=null)
         {
             Console.WriteLine(
"發行刊物");
             OnPublish();
         }
     }
 }
 
class Subscriber//訂閱者
 {
     
public void Receive()//在事件訂閱者中定議事件處理程序
     {
         Console.WriteLine(
"訂閱者已經收到刊物");    
     }
 }
 
class Story
 {
     
static void Main()
     {
         Publisher Pub
=new Publisher();
         Subscriber zs
=new Subscriber();
         Pub.OnPublish
+=new Publisher.Publish(zs.Receive);//向事件發行者訂閱一個事件
         Pub.issue();//觸發事件
     }
 }

/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2008/9/2
 * Time: 下午 11:39
 * 事件(event)
 * 
 * 
 * 事件的四個步驟
 * 1,在事件發行者中定議一個事件
 * 2,在事件發行者中觸發事件
 * 3,在事件訂閱者中定議事件處理程序
 * 4,向事件發行者訂閱一個事件
 
*/
 
using System;
 
class Publisher//出版社
 {
     
public delegate void PubComputer(string magazineName);//聲明事件所需的代理
     public delegate void PubLife(string magazineName);
     
public event PubComputer OnPubComputer;
     
public event PubLife OnPubLife;//事件的聲明
     public void issueComputer()//觸發事件的方法
     {
         
if(OnPubComputer!=null)
         {
             Console.WriteLine(
"發行<<電腦>>雜志");
             OnPubComputer(
"電腦雜志");
         }
     }
     
public void issueLife()
     {
         
if(OnPubLife!=null)
         {
             Console.WriteLine(
"發行<<生活>>雜志");
             OnPubLife(
"生活雜志");
         }
     }
 }
 
class Subscriber//訂閱者
 {
     
private string name;
     
public Subscriber(string name_)
     {
         
this.name=name_;
     }
     
public void Receive(string magazineName)//在事件訂閱者中定議事件處理程序
     {
         Console.WriteLine(name 
+ "已經收到" + magazineName);    
     }
 }
 
class Story
 {
     
static void Main()
     {
         
//事件發行者只會把事件發關給訂閱的用戶
         Publisher Pub=new Publisher();
         Subscriber zs
=new Subscriber("張三");
         Pub.OnPubComputer
+=new Publisher.PubComputer(zs.Receive);//向事件發行者訂閱一個事件
         Subscriber ls=new Subscriber("李四");
         Pub.OnPubComputer
+=new Publisher.PubComputer(ls.Receive);
         Pub.OnPubLife
+=new Publisher.PubLife(ls.Receive);
         Pub.issueComputer();
         Pub.issueLife();
         Console.WriteLine();
         Console.WriteLine(
"一年以後李四不再訂閱<<電腦>>雜志");
         Pub.OnPubComputer
-=new Publisher.PubComputer(ls.Receive);
         Pub.issueComputer();
         Pub.issueLife();        
     }
 }

/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2008/9/2
 * Time: 下午 11:39
 * 事件(event)
 * 
 * .NET Framework事件設計準則
 * 1,事件的命名準則使用PascalCasing命名方式
 * 2,聲明delegate時,使用void類型當作返回值,EventName事件的事件
 * 委托是EventNameEventHandler,事件接受兩個傳入參數,一力命名為
 * sender與e.
 * 3,定議一個提供中件數據的類.對類以EventNameEventArgs進行命名,
 * 從System.EventArgs派生該類,然後添加所有事件特定的成員.
 * 
 * public delegate vodi EventNameEventHandler(object sender,EventNameEventArgs e);
 * 
 * 下面的過程說明如何在婁中實現事件.如果事件不需要傳遞
 * 任何數據,也要聲明兩個參數,e參數可以直接使用系統提供
 * 的System.EventArgs類.如果需要傳遞數據,則要從
 * System.EventArgs繼承一個類,並把數據放在里面.
 * public delegate void EventNameEventHandler(object sender,EventArgs e);
 * public event EventNameEventHandler EventName;
 * 
 * 
 * 在引發事件的類中提供一個受保護的方法.
 * [主要是為了防止線程同步]
 * 以OnEventName進行命名.在該方法中引發該事件
 * protected virtual void OnEventName(EventArgs e)
 * {
 *     if(EventName!=null)
 *     {
 *         EventName(this,e);
 *     }
 * }
 * 下面我們就按設計準則來改寫前一個例子.
 
*/
 
using System;
 
class PubEventArgs : EventArgs
 {
     
private readonly string _magazinename;
     
private readonly DateTime _pubdate;
     
public PubEventArgs(string magazineName,DateTime pubDate)
     {
         
this._magazinename=magazineName;
         
this._pubdate=pubDate;
     }
     
public string magazineName
     {
         
get { return this._magazinename; }
     }
     
public DateTime pubDate
     {
         
getreturn this._pubdate ; }
     }            
 }
 
class Publisher//出版社
 {
     
public delegate void PubComputerEventHandler(object sender,PubEventArgs e);//聲明事件所需的代理
     public delegate void PubLifeEventHandler(object sender,PubEventArgs e);
     
public event PubComputerEventHandler PubComputer;//定議事件
     public event PubLifeEventHandler PubLife;//定議事件
     
//定議受保護的方法此方法主要是防止線程同步
     protected virtual void OnPubComputer(PubEventArgs e)
     {
         PubComputerEventHandler handler
=PubComputer;
         
if(handler!=null)
         {
             handler(
this,e);
         }
     }
     
//定議受保護的方法此方法主要是防止線程同步
     protected virtual void OnPubLife(PubEventArgs e)
     {
         PubLifeEventHandler handler
=PubLife;
         
if(handler!=null)
         {
             handler(
this,e);
         }
     }
     
//定議觸發事件的方法
     public void issueComputer(string magazineName,DateTime pubDate)//觸發事件的方法
     {
         Console.WriteLine(
"發行" + magazineName);
         OnPubComputer(
new PubEventArgs(magazineName,pubDate));
     }
     
//定議觸發事件的方法
     public void issueLife(string magazineName,DateTime pubDate)
     {
         Console.WriteLine(
"發行" + magazineName);
         OnPubLife(
new PubEventArgs(magazineName,pubDate));
     }
 }
 
class Subscriber//訂閱者
 {
     
private string _name;
     
public Subscriber(string name)
     {
         
this._name=name;
     }
     
public void Receive(object sender,PubEventArgs e)//在事件訂閱者中定議事件處理程序
     {
 
         Console.WriteLine(e.pubDate 
+ " " + _name + "已經收到" + e.magazineName);    
     }
 }
 
class Story
 {
     
static void Main()
     {
         
//事件發行者只會把事件發關給訂閱的用戶
         Publisher Pub=new Publisher();
         Subscriber zs
=new Subscriber("張三");
         Pub.PubComputer
+=new Publisher.PubComputerEventHandler(zs.Receive);//向事件發行者訂閱一個事件
         Subscriber ls=new Subscriber("李四");
         Pub.PubComputer
+=new Publisher.PubComputerEventHandler(ls.Receive);
         Pub.PubLife
+=new Publisher.PubLifeEventHandler(ls.Receive);
         Pub.issueComputer(
"電腦雜志",Convert.ToDateTime("2006-1-1"));
         Pub.issueLife(
"生活雜志",Convert.ToDateTime("2006-1-1"));
         Console.WriteLine();
         Console.WriteLine(
"一年以後李四不再訂閱<<電腦>>雜志");
         Pub.PubComputer
-=new Publisher.PubComputerEventHandler(ls.Receive);
         Pub.issueComputer(
"電腦雜志",Convert.ToDateTime("2007-1-1"));
         Pub.issueLife(
"生活雜志",Convert.ToDateTime("2007-1-1"));        
     }
 }


/*關於事件的說法:
 * 1,委托是一种自定的類型,委托定議了方法的類型.
 * 2,事件是委托的實例.使用委托實例的委托鏈注刪一些方法.
 * 使用+=註冊,-=撤銷
 * 3,當事件發生的時候,調用委托鏈中的這些方法.
 * 不妨稱這些方法為事件處理函數.
 * 
 * 下面的例子是
 * 熱水器發出水開的事件
 * 警報器接受這個事件,做出相應的動作.
 * 顯示器接受這個事件,做出相應該的動作.
 * 
 * 如果想讓報警器和顯示器能接受到這個事件,
 * 那麼方法需註冊這個事件.
 
*/
using System;
using Delegate;
//熱水器
namespace Delegate
{
    
public class Heater
    {
        
private int temperature=0;//聲明成員變量
        public delegate void BoilHandler(int param);//聲明委托
        public event BoilHandler BoilEvent;//聲明事件,委托的對像
        public void BoilWater()//水的方法
        {
            
for(int i=1;i<=100;i++)
            {
                
this.temperature++;
                
if(this.temperature>=99 && BoilEvent!=null)
                {
                    BoilEvent(
this.temperature);//調用所註冊的方法
                }
            }
        }
    }
    
//警報器
    public class Alarm
    {
        
public void MakeAlert(int param)//參數也是就是簽名和委托的是一至的
        {
            Console.WriteLine(
"水開了,度數為:" + param.ToString());
        }
    }
    
//顯示器
    public class Display
    {
        
public void ShowMsg(int param)
        {
            Console.WriteLine(
"顯示當前度數為:" + param.ToString());
        }
    }
}
namespace Athrun
{
    
class Test
    {
        
static void Main()
        {
            Heater heater
=new Heater();
            Alarm alarm
=new Alarm();
            Display display
=new Display();
            heater.BoilEvent
+=alarm.MakeAlert;//註冊方法
            heater.BoilEvent+=display.ShowMsg;//註冊方法
            heater.BoilEvent-=display.ShowMsg;//刪除方法
            heater.BoilWater();//溫度到達99時角發事件
        }
    }
}

申明

非源创博文中的内容均收集自网上,若有侵权之处,请及时联络,我会在第一时间内删除.再次说声抱歉!!!

博文欢迎转载,但请给出原文连接。

原文地址:https://www.cnblogs.com/Athrun/p/1282662.html