Delegate delegate是C#中的一種類型,它實際上是一個能夠持有對某個方法的引用的類。與其它的類不同,delegate類能夠擁有一個簽名(signature),并且它隻能持有與它的簽名相比對的方法的引用。它所實作的功能與C/C++中的函數指針十分相似。它允許你傳遞一個類A的方法m給另一個類B的對象,使得類B的對象能夠調用這個方法m。但與函數指針相比,delegate有許多函數指針不具備的優點。首先,函數指針隻能指向靜态函數,而delegate既可以引用靜态函數,又可以引用非靜态成員函數。在引用非靜态成員函數時,delegate不但儲存了對此函數入口指針的引用,而且還儲存了調用此函數的類執行個體的引用。其次,與函數指針相比,delegate是面向對象、類型安全、可靠的受控(managed)對象。也就是說,runtime能夠保證delegate指向一個有效的方法,你無須擔心delegate會指向無效位址或者越界位址。 實作一個delegate是很簡單的,通過以下3個步驟即可實作一個delegate: 1.聲明一個delegate對象,它應當與你想要傳遞的方法具有相同的參數和傳回值類型。 2. 建立delegate對象,并将你想要傳遞的函數作為參數傳入。 3. 在要實作異步調用的地方,通過上一步建立的對象來調用方法。using System;
public class MyDelegateTest { // 步驟1,聲明delegate對象 public delegate void MyDelegate(string name); // 這是我們欲傳遞的方法,它與MyDelegate具有相同的參數和傳回值類型 public static void MyDelegateFunc(string name) { Console.WriteLine("Hello, ", name); } public static void Main() { // 步驟2,建立delegate對象 MyDelegate md = new MyDelegate(MyDelegateTest.MyDelegateFunc); // 步驟3,調用delegate md("sam1111"); } } 輸出結果是:Hello, sam1111
了解了delegate,下面我們來看看,在C#中對事件是如何處理的。 C#中的事件處理實際上是一種具有特殊簽名的delegate,象下面這個樣子: public delegate void MyEventHandler(object sender, MyEventArgs e); 其中的兩個參數,sender代表事件發送者,e是事件參數類。MyEventArgs類用來包含與事件相關的資料,所有的事件參數類都必須從System.EventArgs類派生。當然,如果你的事件不含參數,那麼可以直接用System.EventArgs類作為參數。 就是這麼簡單,結合delegate的實作,我們可以将自定義事件的實作歸結為以下幾步: 1.定義delegate對象類型,它有兩個參數,第一個參數是事件發送者對象,第二個參數是事件參數類對象。 2.定義事件參數類,此類應當從System.EventArgs類派生。如果事件不帶參數,這一步可以省略。 3.定義事件處理方法,它應當與delegate對象具有相同的參數和傳回值類型。 4. 用event關鍵字定義事件對象,它同時也是一個delegate對象。 5.用+=操作符添加事件到事件隊列中(-=操作符能夠将事件從隊列中删除)。 6.在需要觸發事件的地方用調用delegate的方式寫事件觸發方法。一般來說,此方法應為protected通路限制,既不能以public方式調用,但可以被子類繼承。名字是OnEventName。 7. 在适當的地方調用事件觸發方法觸發事件。 下面是一個簡單的例子:
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 = Console.ReadLine(); if(s == "a") { et.RaiseEvent(); } else { Console.WriteLine("Error"); } } } 輸出結果如下,紅色為使用者的輸入: Please input ‘a’: a My event is ok!
posted @ 2007-07-03 15:41 guo 閱讀(532) | 評論 (0) | 編輯
2007年6月26日
頁面輪換圖檔的一個執行個體
<!--廣告輪播--> <div id="lb"> <div id="pic" onClick="getUrl(0);"><img id="ackPic" src="/pic/ad8.jpg" style="FILTER: revealTrans(duration=2,transition=20)"></div> <div id="lbres"><a href=" http://lady.cheapu.net/ladyview/14" target="_blank">男人最害怕女性的五大妝扮</a></div> </div> <script> var imgUrl=[[" http://new.cheapu.net/mini/pic/lb1.gif%22,%22http://www.cheapu.net/s3460.htm","暇步士夏品特賣7折起"], [" http://new.cheapu.net/mini/pic/lb2.gif%22,%22http://www.cheapu.net/s3456.htm","哈根達斯消費500元即辦9折卡"], [" http://new.cheapu.net/mini/pic/lb3.gif%22,%22http://www.cheapu.net/s3452.htm","黛安芬内衣指定款買一送一"], [" http://new.cheapu.net/mini/pic/lb4.gif%22,%22http://www.cheapu.net/s3506.htm","歐珀萊均衡1-2-3買贈開始"], [" http://new.cheapu.net/mini/pic/lb5.gif%22,%22http://www.cheapu.net/s2833.htm","雙安商場[思加圖]5折起賣"]]; var adNum=0; var doFlag=true; function getP(v) { adNum=v;nextAd(true); } function nextAd(bool){ if(doFlag){ if (document.all){ try{ackPic.filters.revealTrans.Transition=Math.floor(Math.random()*23);ackPic.filters.revealTrans.apply();}catch(e){};} ackPic.src=imgUrl[adNum][0]; lbres.innerHTML="<a href='"+imgUrl[adNum][1]+"' target=_blank>"+imgUrl[adNum][2]+"</a>"; if (document.all){try{ackPic.filters.revealTrans.play();}catch(e){}} if(adNum<imgUrl.length-1)adNum++; else adNum=0; } if(bool){setTimeout("nextAd()",15000);} else{setTimeout("nextAd()",7000);} } function goOn(){doFlag=true;} function goEnd(){doFlag=false;} function getUrl(){if(adNum>0)adNum--;else adNum=imgUrl.length-1; window.open(imgUrl[adNum][1]);} nextAd(); </script>