轉自:http://www.hubwiz.com/
事件(Event) 基本上說是一個用戶操作,如按鍵、點擊、鼠標移動等等,或者是一些出現,如系統生成的通知。應用程序需要在事件發生時響應事件。例如,中斷。事件是用於進程間通信。
事件在類中聲明且生成,且通過使用同一個類或其他類中的委託與事件處理程序關聯。包含事件的類用於發佈事件。這被稱爲 發佈器(publisher) 類。其他接受該事件的類被稱爲 訂閱器(subscriber) 類。事件使用 發佈-訂閱(publisher-subscriber) 模型。
發佈器(publisher) 是一個包含事件和委託定義的對象。事件和委託之間的聯繫也定義在這個對象中。發佈器(publisher)類的對象調用這個事件,並通知其他的對象。
訂閱器(subscriber) 是一個接受事件並提供事件處理程序的對象。在發佈器(publisher)類中的委託調用訂閱器(subscriber)類中的方法(事件處理程序)。
事件聲明
事件和方法一樣具有簽名,簽名包括名稱和參數列表。事件的簽名通過委託類型來定義,然後向類中添加事件需要使用 event 關鍵字,並提供委託類型和事件名稱。例如:
public delegate void TestEventDelegate(object sender, System.EventArgs e);
public class EventSource
{
public event TestEventDelegate TestEvent; //基於上面的委託
private void RaiseTestEvent() { /* ... */ }
}
事件可標記爲 public、private、protected、internal 或 protected internal。這些訪問修飾符定義類的用戶訪問事件的方式。
自定義事件
C#中的事件處理實際上是一種具有特殊簽名的delegate,象下面這個樣子:
public delegate void MyEventHandler(object sender, MyEventArgs e);
其中的兩個參數,sender代表事件發送者,e是事件參數類。MyEventArgs類用來包含與事件相關的數據,所有的事件參數類都必須從System.EventArgs類派生。
結合delegate的實現,我們可以將自定義事件的實現歸結爲以下幾步:
定義delegate對象類型,它有兩個參數,第一個參數是事件發送者對象,第二個參數是事件參數類對象。
定義事件參數類,此類應當從System.EventArgs類派生。如果事件不帶參數,這一步可以省略。
定義"事件處理方法,它應當與delegate對象具有相同的參數和返回值類型"。
用event關鍵字定義事件對象,它同時也是一個delegate對象。
用+=操作符添加事件到事件隊列中(-=操作符能夠將事件從隊列中刪除)。
在需要觸發事件的地方用調用delegate的方式寫事件觸發方法。一般來說,此方法應爲protected訪問限制,既不能以public方式調用,但可以被子類繼承。名字是OnEventName。
在適當的地方調用事件觸發方法觸發事件。
以下代碼的功能是輸入'a'觸發事件。
using System;
public class EventTest
{
// 步驟1,定義delegate對象
public delegate void MyEventHandler(object sender, System.EventArgs e);
// 步驟2(定義事件參數類)省略
public class MyEventCls
{
// 步驟3,定義事件處理方法,它與delegate對象具有相同的參數和返回值類型
public void MyEventFunc(object sender, System.EventArgs e)
{
Console.WriteLine("My event is ok!");
}
}
// 步驟4,用event關鍵字定義事件對象
private event MyEventHandler myevent;
private MyEventCls myecls;
public EventTest()
{
myecls = new MyEventCls();
// 步驟5,用+=操作符將事件添加到隊列中
this.myevent += new MyEventHandler(myecls.MyEventFunc);
}
// 步驟6,以調用delegate的方式寫事件觸發函數
protected void OnMyEvent(System.EventArgs e)
{
if (myevent != null)
myevent(this, e);
}
public void RaiseEvent()
{
EventArgs e = new EventArgs();
// 步驟7,觸發事件
OnMyEvent(e);
}
public static void Main()
{
EventTest et = new EventTest();
Console.Write("Please input ''a'':");
string s = "a";
Console.WriteLine(s);
if (s == "a")
{
et.RaiseEvent();
}
else
{
Console.WriteLine("Error");
}
}
}
匿名方法
委託是用於引用與其具有相同標籤的方法。換句話說,使用委託對象調用可由委託引用的方法。
匿名方法(Anonymous methods) 提供了一種傳遞代碼塊作爲委託參數的技術。匿名方法是沒有名稱只有主體的方法,不需要指定返回類型,它是從方法主體內的 return 語句推斷的。
匿名方法是通過使用 delegate 關鍵字創建委託實例來聲明的。例如:
delegate void NumberChanger(int n);
NumberChanger nc = delegate(int x)
{
Console.WriteLine("Anonymous Method: {0}", x);
};
委託可以通過匿名方法調用,也可以通過命名方法調用,即,通過向委託對象傳遞方法參數。如上面的可以調用爲:
nc(1);
下面通過實例來了解一下匿名方法。
using System;
namespace test
{
delegate void Printer(string s); //聲明委託
class TestClass
{
static void Main()
{
// 初始化匿名方法
Printer p = delegate(string j)
{
System.Console.WriteLine(j+" anonymous method");
};
p("The delegate using the method is called:"); //調用匿名方法
p = new Printer(TestClass.DoWork); //實例化委託
p("using the named method is called: ");//調用DoWork方法
}
static void DoWork(string k)
{
System.Console.WriteLine(k + "dowork");
}
}
}