在c#中沒有c++中的函式指標的概念,但是有委託的概念,功能與函式指標類似。
c# 中的委託(delegate)類似於 c 或 c++ 中函式的指標。委託(delegate)是存有對某個方法的引用的一種引用型別變數。引用可在執行時被改變。
委託(delegate)特別用於實現事件和**方法。所有的委託(delegate)都派生自system.delegate類。
實現乙個delegate是很簡單的,通過以下3個步驟即可實現乙個delegate:
1. 宣告乙個delegate物件,它應當與你想要傳遞的方法具有相同的引數和返回值型別。
2. 建立delegate物件,並"將你想要傳遞的函式作為引數傳入"。
3. 在要實現非同步呼叫的地方,通過上一步建立的物件來呼叫方法。
委託宣告決定了可由該委託引用的方法。委託可指向乙個與其具有相同標籤的方法。
例如,假設有乙個委託:
publicdelegate
intmydelegate
(string
s);
上面的委託可被用於引用任何乙個帶有乙個單一的 string 引數的方法,並返回乙個 int 型別變數。
宣告委託的語法如下:
delegate一旦宣告了委託型別,委託物件必須使用new關鍵字來建立,且與乙個特定的方法有關。當建立委託時,傳遞到new語句的引數就像方法呼叫一樣書寫,但是不帶有引數。例如:<
return
type
>
<
delegate
-name
>
<
parameter list
>
publicdelegate
void
printstring
(strings);
...printstring ps1
=new
printstring
(writetoscreen
);printstring ps2
=new
printstring
(writetofile
);
委託物件可使用 "+" 運算子進行合併。乙個合併委託呼叫它所合併的兩個委託。只有相同型別的委託可被合併。"-" 運算子可用於從合併的委託中移除元件委託。
使用委託的這個有用的特點,您可以建立乙個委託被呼叫時要呼叫的方法的呼叫列表。這被稱為委託的多播(multicasting),也叫組播。下面的程式演示了委託的多播:
using system;
delegate int numberchanger(int n);
public static int multnum(int q)
public static int getnum()
static void main(string args)
", getnum());
console.readkey();}}
}
委託的多播例項二
// 小張類
public class mrzhang
public static void buymovieticket()
}//小明類
class mrming
}
下面的例項演示了委託的用法。委託 printstring 可用於引用帶有乙個字串作為輸入的方法,並不返回任何東西。
我們使用這個委託來呼叫兩個方法,第乙個把字串列印到控制台,第二個把字串列印到檔案:
using system;
using system.io;
namespace delegate1
",str);
} //將方法列印到檔案
public static void writetofile(string s)
//該方法把委託作為引數,並使用它呼叫方法
public static void sendstring(printstring ps)
static void main(string args)
}}
事件(event)基本上說是乙個使用者操作,如按鍵、點選、滑鼠移動等等,或者是一些出現,如系統生成的通知。應用程式需要在事件發生時響應事件。例如,中斷。事件是用於程序間通訊。
事件在類中宣告且生成,且通過使用同乙個類或其他類中的委託與事件處理程式關聯。包含事件的類用於發布事件。這被稱為發布器(publisher)類。其他接受該事件的類被稱為訂閱器(subscriber)類。事件使用發布-訂閱(publisher-subscriber)模型。
發布器(publisher)是乙個包含事件和委託定義的物件。事件和委託之間的聯絡也定義在這個物件中。發布器(publisher)類的物件呼叫這個事件,並通知其他的物件。
訂閱器(subscriber)是乙個接受事件並提供事件處理程式的物件。在發布器(publisher)類中的委託呼叫訂閱器(subscriber)類中的方法(事件處理程式)。
在類的內部宣告事件,首先必須宣告該事件的委託型別。例如:
public然後,宣告事件本身,使用event關鍵字:delegate
void
boilerloghandler
(string
status
);
// 基於上面的委託定義事件上面的**定義了乙個名為 boilerloghandler 的委託和乙個名為 boilereventlog 的事件,該事件在生成的時候會呼叫委託。public
event
boilerloghandler
boilereventlog
;
舉例一
using system;
namespace event1
} class classb }
class myclass
}} class program }
}
舉例二
using system;
using system.io;
public int gettemp()
public int getpressure()
}// 事件發布器
class delegateboilerevent
onboilereventlog("logging info:\n");
onboilereventlog("temparature " + t + "\npressure: " + p);
onboilereventlog("\nmessage: " + remarks);
}protected void onboilereventlog(string message)}}
// 該類保留寫入日誌檔案的條款
class boilerinfologger
public void logger(string info)
public void close()
}// 事件訂閱器
public class recordboilerinfo
//end of logger
static void main(string args)
//end of main
}//end of recordboilerinfo
}
委託 三 委託與介面的區別
何時使用委託?何時介面?在以下情況中使用委託 1.當使用事件設計模式時.2.當封裝靜態方法可取時.3.當呼叫方不需要訪問實現該方法的物件中的其他屬性.方法或介面時.4.需要方便的組合.5.當類可能需要方法的多個實現時.在以下情況使用介面 1.當存在一組可能被呼叫的相關方法時 2.當類只需要方法的單個...
C 委託與事件的區別
事件是利用委託來申明的,因此先解釋委託。委託是乙個類,它與其他類如int,string等沒有本質區別,int代表的是所有的整形,而string代表的是字串,委託則代表的是一類方法,這類方法具有相同返回型別和相同引數。委託的定義 public delegate void calculatorhandl...
C 委託與事件講解 三
protected void btnsearch click object sender,imageclickeventargs e 那他們到底表示什麼呢?在回答上面的問題之前,我們先搞懂 net framework的編碼規範 一 委託型別的名稱都應該以eventhandler結束。二 委託的原型定...