導航:首頁 > 方法技巧 > C委託鏈上的方法如何執行

C委託鏈上的方法如何執行

發布時間:2022-05-11 14:34:37

A. 請問C#中的委託是什麼如何使用

委託的用法很多:一般是用於聲明事件和回調的委託,還可以是用於代表方法標簽的委託.
書本上的委託只是對委託的定義與具體怎樣調用問題,沒有涉及到委託的真正實用的地方。其實委託是與事件和回調
一起來使用的,你可以看一下C#非同步調用,與多線程處理里等就可以看到委託的作用了。
下面是別人的理解我覺得還是比較好的:
1)有了委託你就可以把方法看作像常數一樣,而委託就是該常數類型的變數.
從這個角度看來用於聲明事件的委託就是聲明這個事件觸發以後所調用的方法的標簽或者特徵.只有符合該標簽(參數個數和參數類型)的方法才可以做為該用於該事件的回調.
一個事件觸發了,你可能需要用多個方法處理該事件或者說該事件調用了多個方法(每個事件的實例都有一個需要調用的方法列表,當事件觸發它會逐個調用列表中的每個方法)
2)通過使用委託你可以實現對方法變化的封裝.
打個比方:如果你騎自行車,你需要有騎自行車的方法DriveBike().如果你騎摩托車你需要有騎摩托車的方法.現在你有一個方法DriveMoto.現在你需要定義一個方法,實現你騎(自行車或者摩托車)到某地DriveTo(地點,騎的方式)
騎的方式這里其實就是委託.在使用的時候,如果你是騎自行車你就用DriveBike實例化委託的實例帶入DriveTo方法,如果你騎摩托車你就用DriveMoto實例化"騎的方式"這個委託帶入DriveTo方法.

B. C#中的委託到底是什麼概念

委託,簡單理解是這樣的.
比如您要管您的孩子,把孩子送進了幼兒園.
OK.此時您就把您的孩子委託給了幼兒園.
當幼兒園放學,將孩子交還給您的手中.則是委託的回調.
當然我這里的例子是說非同步委託調用.您也可以同步.
什麼是同步委託調用?
您去銀行存錢.把錢給櫃員.他們幫你點鈔.存款然後給您存摺或卡.
那麼您就相當於把錢委託給了櫃員讓他去執行存錢的這個函數.
明白了么?

Delegate
delegate是C#中的一種類型,它實際上是一個能夠持有對某個方法的引用的類。與其它的類不同,delegate類能夠擁有一個簽名(signature),並且它"只能持有與它的簽名相匹配的方法的引用"。它所實現的功能與C/C++中的函數指針十分相似。它允許你傳遞一個類A的方法m給另一個類B的對象,使得類B的對象能夠調用這個方法m。但與函數指針相比,delegate有許多函數委託和事件在 .Net Framework中的應用非常廣泛指針不具備的優點。首先,函數指針只能指向靜態函數,而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!

C. c#委託鏈的問題

你的委託d1上的確已經掛上了兩個方法,當d1被調用的時候,那兩個方法也的確都被觸發調用到了。
不過多個方法有多個返回值,而只有一個變數來接受,所以後面被調用的方法的返回值,就把前面方法的返回值覆蓋掉了。換句話說,前面的返回值都被丟棄掉了。

這也是定義事件委託的時採用void作為返回值的原因。

【回答補充】

你可以去看看系統類庫提供的委託/事件,都是void返回類型的。

如果你非要做一個帶返回值的委託,那可以這樣做了:
......
public string CreateDelegate()
{
Class1 c1 = new Class1();
MyDelegate d1 = new MyDelegate(c1.delegateMethod1);
d1 += c1.delegateMethod2;
string d = "";
foreach (MyDelegate x in d1.GetInvocationList())
{
d += x("Hello World");
}
return d;
}
......

D. c# 委託是怎麼回事怎麼用

讓我來告訴你吧
委託是什麼?委託是函數指針。函數指針是什麼?是能夠運行某(幾)個函數(方法)的代碼。

舉個例子
void static main(){
do();
}
void static do(){
int a = 0;
}

這個好理解吧。。。在main函數內調用do函數。
能夠這樣寫,是因為do的代碼(int a = 0;)是已知的。但是,假如在main函數內要調用do函數,卻不知道do函數的內容是怎樣的,該怎麼辦呢?

void static main(Adelegate do){
do();
}
do就是一個委託。我們不知道do是怎樣寫的,我們只知道do函數的參數為空。這就是所謂函數指針--僅在運行時才知道函數的代碼。

補充-----------------------------------
比如說windows消息循環就是這種模式。
舉個例子。
假如你是微軟,你寫了一個button控制項,他的功能是:當滑鼠點擊時做點什麼。代碼可能像這樣
while(true){
do();//做點什麼
}
問題是:微軟怎麼知道你要做點什麼呢?1000個程序員可以給出1000個答案。
程序員a想顯示一條信息,程序員b想打開一個網站。。。
因此,微軟不可能自己實現do方法,把它交給人家去做吧!
於是代碼改為
public ClickedEventHandler OnClick();//ClickedEventHandler是一個委託
while(true){
if (OnClick != null)
OnClick();
}

程序員a就能這樣寫代碼了:
Button b = new Button();
b.OnClick += new ClickedEventHandler(do());
.................

privte void do(){
MessageBox.Show("haha");
}
點擊按鈕時,就可以看到'haha'字樣了。

當然,不是所有委託都要表示成事件,但事件確是最典型的委託。

E. C# 中 用委託有什麼好處 它起什麼作用

什麼是委託
首先要知道什麼是委託,用最通俗易懂的話來講,你就可以把委託看成是用來執行方法(函數)的一個東西。

如何使用委託
在使用委託的時候,你可以像對待一個類一樣對待它。即先聲明,再實例化。只是有點不同,類在實例化之後叫對象或實例,但委託在實例化後仍叫委託。

聲明,如:

1 namespace Vczx.ProCSharp.Exc
2 {
3 delegate double MathsOp( double x );
4 //class defination here
5 }

這就聲明了一個委託,意義:任何一個返回值為double,且只有一個形參為double的函數,都可以用這個委託來調用。
注意:委託的聲明位置在namespace裡面,類的外面。其實,委託的聲明也可以在類的裡面,甚至是任何一個可以聲明類的地方。
實例化:
首先我們要先有一個滿足委託聲明的方法,假設一個返回一個數的2倍的方法:

1class MathsOperations
2{
3 public static double MultiplyBy2( double value )
4 {
5 return value * 2;
6 }
7}

有了這樣一個方法,我們就可以實例化一個委託了:
MathsOp operation = new MathsOp( MathsOperations.MultiplyBy2 );
在實例化一個委託時,要給它一個參數,這個參數就是委託執行的方法,它可以是靜態方法,也可以是實例方法(這一點有別於函數指針,函數指針只能調用靜態方法),如:
MathsOp operation = new MathsOp( new Class1().Method1 );

在實例化完一個委託之後,就可以用這個委託來調用方法了:
double result = operation( 1.23 );

例子代碼:

1namespace Vczx.ProCSharp.Exc
2{
3 delegate double MathsOp( double x );
4 class Start
5 {
6 public class MyDelegate
7 {
8 public static double MultiplyBy2( double x )
9 {
10 return x * 2;
11 }
12 }
13 [STAThread]
14 static void Main(string[] args)
15 {
16 MathsOp operation = new MathsOp( MyDelegate.MultiplyBy2 );
17 double x = 1.23;
18 double result = operation( x );
19 Console.WriteLine( "{0} multiply by 2 is {1}", x, result );
20 Console.Read();
21 }
22 }
23}

多路廣播委託
前面使用的委託只包含一個方法調用。調用委託的次數與調用方法的次數相同。如果要調用多個方法,就需要多次顯示調用這個委託。其實委託也可以包含多個方法,這種委託就是多路廣播委託。多路廣播委託派生於System.MulticastDelegate,它的Combine方法允許把多個方法調用鏈接在一起,我們可以通過+=來向委託添加調用方法,也可以用-=刪除其中的調用方法。如:

1namespace Vczx.ProCSharp.Exc
2{
3 public class MyDelegate
4 {
5 public static void MultiplyBy2( double value )
6 {
7 double result = value * 2;
8 Console.WriteLine( "Multiplying by 2: {0} gives {1}", value, result );
9 }
10
11 public static void Squre( double value )
12 {
13 double result = value * value;
14 Console.WriteLine( "Squaring: {0} gives {1}", value, result );
15 }
16 }
17
18 delegate void MathsOp( double x );
19
20 class Start
21 {
22 [STAThread]
23 static void Main(string[] args)
24 {
25 MathsOp operation = new MathsOp( MyDelegate.MultiplyBy2 );
26 operation += new MathsOp( MyDelegate.Squre );
27 double x = 1.23;
28 operation( x );
29
30 operation -= new MathsOp( MyDelegate.MultiplyBy2 );
31 operation( x );
32
33 Console.Read();
34 }
35 }
36}

輸出:
Multiplying by 2: 1.23 gives 2.46
Squaring: 1.23 gives 1.5129
Squaring: 1.23 gives 1.5129

注意,多路廣播委託聲明時必須返回void,否則返回值不知道應該送回什麼地方。對此,我做了一個測試:如果不將委託的聲明返回void,則返回值返回的是最後一個鏈入委託鏈的方法的返回值,編譯不會出錯。

為什麼要用委託
使用委託使程序員可以將方法引用封裝在委託對象內。然後可以將該委託對象傳遞給可調用所引用方法的代碼,而不必在編譯時知道將調用哪個方法。與C或C++中的函數指針不同,委託是面向對象,而且是類型安全的。

F. C#中通過委託來調用對象方法的基本過程

delegate翻譯過來是委託!

在C#中使用一個類時,分兩個階段。首先需要定義這個類,即告訴編譯器這個類由什麼欄位和方法組成。然後(除非只使用靜態方法)實例化類的一個對象。使用委託時,也需要經過這兩個步驟。首先定義要使用的委託,對於委託,定義它就是告訴編譯器這種類型代表了哪種類型的方法,然後創建該委託的一個或多個實例。
定義委託的語法如下:
delegate void VoidOperation(uint x);
在這個示例中,定義了一個委託VoidOperation,並指定該委託的每個實例都包含一個方法的細節,該方法帶有一個uint參數,並返回void。理解委託的一個要點是它們的類型安全性非常高。在定義委託時,必須給出它所代表的方法的全部細節。
提示:
理解委託的一種好方式是把委託的作用當作是給方法簽名指定名稱。
假定要定義一個委託TwoLongsOp ,該委託代表的函數有兩個long型參數,返回類型為double型,可以編寫如下代碼:
delegate double TwoLongsOp(long first, long second);
或者定義一個委託,它代表的方法不帶參數,返回一個string型的值,則可以編寫如下代碼:
delegate string GetAString();
其語法類似於方法的定義,但沒有方法體,定義的前面要加上關鍵字delegate。因為定義委託基本上是定義一個新類,所以可以在定義類的任何地方定義委託,既可以在另一個類的內部定義,也可以在任何類的外部定義,還可以在命名空間中把委託定義為頂層對象。根據定義的可見性,可以在委託定義上添加一般的訪問修飾符:public、 private和 protected等:
public delegate string GetAString();
注意:
實際上,「定義一個委託」是指「定義一個新類」。委託實現為派生於基類System.MulticastDelegate的類,System.MulticastDelegate又派生於基類System.Delegate。C#編譯器知道這個類,使用其委託語法,因此我們不需要了解這個類的具體執行情況,這是C#與基類共同合作,使編程更易完成的另一個示例。
定義好委託後,就可以創建它的一個實例,以存儲特定方法的細節。
注意:
此處,在術語方面有一個問題。類有兩個不同的術語:「類」表示較廣義的定義,「對象」表示類的實例。但委託只有一個術語。在創建委託的實例時,所創建的委託的實例仍稱為委託。您需要從上下文中確定委託的確切含義。
下面的代碼段說明了如何使用委託。這是在int上調用ToString()方法的一種相當冗長的方式:
private delegate string GetAString();

static void Main(string[] args)
{
int x = 40;
GetAString firstStringMethod = new GetAString(x.ToString);
Console.WriteLine("String is" + firstStringMethod());
// With firstStringMethod initialized to x.ToString(),
// the above statement is equivalent to saying
// Console.WriteLine("String is" + x.ToString());
在這段代碼中,實例化了類型為GetAString的一個委託,並對它進行初始化,使它引用整型變數x的ToString()方法。在C#中,委託在語法上總是帶有一個參數的構造函數,這個參數就是委託引用的方法。這個方法必須匹配最初定義委託時的簽名。所以在這個示例中,如果用不帶參數、返回一個字元串的方法來初始化firstStringMethod,就會產生一個編譯錯誤。注意,int.ToString()是一個實例方法(不是靜態方法),所以需要指定實例(x)和方法名來正確初始化委託。
下一行代碼使用這個委託來顯示字元串。在任何代碼中,都應提供委託實例的名稱,後面的括弧中應包含調用該委託中的方法時使用的參數。所以在上面的代碼中,Console.WriteLine()語句完全等價於注釋語句中的代碼行。
委託的一個特徵是它們的類型是安全的,可以確保被調用的方法簽名是正確的。但有趣的是,它們不關心調用該方法的是什麼類型的對象,甚至不考慮該方法是靜態方法,還是實例方法。
提示:
給定委託的實例可以表示任何類型的任何對象上的實例方法或靜態方法—— 只要方法的特徵匹配於委託的特徵即可。
為了說明這一點,我們擴展上面的代碼,讓它使用firstStringMethod委託在另一個對象上調用其他兩個方法,其中一個方法是實例方法,另一個方法是靜態方法。為此,再次使用本章前面定義的Currency結構。
struct Currency
{
public uint Dollars;
public ushort Cents;

public Currency(uint dollars, ushort cents)
{
this.Dollars = dollars;
this.Cents = cents;
}
public override string ToString()
{
return string.Format("$.", Dollars,Cents);
}
public static explicit operator Currency (float value)
{
checked
{
uint dollars =(uint)value;
ushort cents =(ushort)((value-dollars)*100);
return new Currency(dollars,cents);
}
}
public static implicit operator float (Currency value)
{
return value.Dollars + (value.Cents/100.0f);
}
public static implicit operator Currency (uint value)
{
return new Currency(value, 0);
}
public static implicit operator uint (Currency value)
{
return value.Dollars;
}
}
Currency結構已經有了自己的ToString()重載方法。為了說明如何使用帶有靜態方法的委託,再增加一個靜態方法,其簽名與Currency的簽名相同:
struct Currency
{
public static string GetCurrencyUnit()
{
return "Dollar";
}
下面使用GetAString 實例,代碼如下所示:
private delegate string GetAString();

static void Main(string[] args)
{
int x = 40;
GetAString firstStringMethod = new GetAString(x.ToString);
Console.WriteLine("String is " + firstStringMethod());
Currency balance = new Currency(34, 50);
firstStringMethod = new GetAString(balance.ToString);
Console.WriteLine("String is " + firstStringMethod());
firstStringMethod = new GetAString(Currency.GetCurrencyUnit);
Console.WriteLine("String is " + firstStringMethod());
這段代碼說明了如何通過委託來調用方法,然後重新給委託指定在類的不同實例上執行的不同方法,甚至可以指定靜態方法,或者在類的不同類型的實例上執行的方法,只要每個方法的特徵匹配於委託定義即可。
但是,我們還沒有說明把一個委託傳遞給另一個方法的具體過程,也沒有給出任何有用的結果。調用int和Currency對象的ToString()的方法要比使用委託直觀得多!在真正領會到委託的用途前,需要用一個相當復雜的示例來說明委託的本質。下面就是兩個委託的示例。第一個示例僅使用委託來調用兩個不同的操作,說明了如何把委託傳遞給方法,如何使用委託數組,但這仍沒有很好地說明沒有委託,就不能完成很多簡單的工作。第二個示例就復雜得多了,它有一個類BubbleSorter,執行一個方法,按照升序排列一個對象數組,這個類沒有委託是很難編寫出來的。

G. C#委託和方法

委託是一個類型安全的對象,它指向程序中另一個以後會被調用的方法(或多個方法)。通俗的說,委託是一個可以引用方法的對象,當創建一個委託,也就創建一個引用方法的對象,進而就可以調用那個方法,即委託可以調用它所指的方法。
1、定義委託類型
[訪問修飾符]delegate 返回類型 委託名(形參);
2、聲明委託對象
委託名 委託實例名;
3、創建委託對象(確定與哪些方法進行綁定)
委託實例名=new 委託名(某個類的方法)
4、使用委託調用方法
委託實例名(實參)

委託注意事項:
1、委託和方法必須具有相同的參數。
2、委託可以調用多個方法,即一個委託對象可以維護一個可調用方法的列表而不是單獨的一個方法,稱為多路廣播(多播)。
3、使用+=和-=運算實現方法的增加和減少
示例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Delegate;

namespace Delegate
{

public delegate int Call(int num1, int num2);//第一步:定義委託類型
class SimpleMath
{
// 乘法方法
public int Multiply(int num1, int num2)
{
return num1 * num2;
}

// 除法方法
public int Divide(int num1, int num2)
{
return num1 / num2;
}
}
}
class Test
{
static void Main(string[] args)
{
Call objCall;//第二步:聲明委託對象
// Math 類的對象
SimpleMath objMath = new SimpleMath();
// 第三步:創建委託對象,將方法與委託關聯起來
objCall = new Call(objMath.Multiply);

Call objCall1 = new Call(objMath.Divide);
objCall += objCall1;//向委託增加一個方法
//objCall -= objCall1;//向委託減去一個方法 // 調用委託實例,先執行objMath.Multiply,然後執行objMath.Divide
int result = objCall(5, 3);
System.Console.WriteLine("結果為 {0}", result);
Console.ReadKey();
}
}

寫法:
1、委託 委託名=new 委託(會調用的方法名); 委託名(參數);
2、委託 委託名 =會調用的方法名; 委託名(參數);
3、匿名方法
委託 委託名=delegate(參數){會調用的方法體};委託名(參數);
4、拉姆達表達式
委託 委託名=((參數1,。。參數n)=>{會調用的方法體});委託名(參數);
5、用Action<T>和Func<T>,第一個無返回值
Func<參數1, 參數2, 返回值> 委託名= ((參數1,參數2) => {帶返回值的方法體 });返回值=委託名(參數1,參數2);

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using @delegate;

namespace @delegate
{
public delegate int Call(int num1, int num2);
class SimpleMath
{
// 乘法方法
public static int Multiply(int num1, int num2)
{
return num1 * num2;
}

// 除法方法
public int Divide(int num1, int num2)
{
return num1 / num2;
}
}
class Test
{
static void Main(string[] args)
{
//--------------------第一種寫法------------------------//
//Call objCall = new Call(SimpleMath.Multiply);
//Call objCall1 = new Call(new SimpleMath().Divide);
//--------------------第二種寫法------------------------//
//Call objCall = SimpleMath.Multiply;
//Call objCall1 = new SimpleMath().Divide;
//--------------------第三種寫法------------------------//
//Call objCall = delegate(int a, int b)
//{
// return a * b;
//};
//Call objCall1 = delegate(int a, int b)
//{
// return a / b;
//};
//--------------------第四種寫法------------------------//
//Call objCall =((int a,int b)=> { return a*b;});
//Call objCall1 = ((int a, int b) => { return a / b; });
//--------------------第五種寫法------------------------//
Func<int, int, int> objCall = ((a, b) => { return a * b; });
Func<int, int, int> objCall1 = ((a, b) => { return a / b; });
Action<int, int> ob = ((a, b) => { Console.WriteLine(a * b); });
ob(5, 3);
//----------------------------------------------------//
int result = objCall(5, 3);
int result1 = objCall1(5, 3);
System.Console.WriteLine("結果1為 {0},結果2為{1}", result,result1);
Console.ReadKey();
}
}
}

H. C#中委託如何使用

1.委託概述
委託是C#中新加入的一個類型,可以把它想作一個和Class類似的一種類型,和使用類相似,使用一個委託時,需要兩個步驟,首先你要定義一個委託,就像是定義一個類一樣;然後,你可以創建一個或多個該委託的實例。
定義一個委託的語法是這樣的:
[public/protected/private] delegate returnType delegateName(paramtype param1,…)
這是我自己寫的,看起來好像有點怪怪的,我來解釋一下,private/protected/private是限定詞,就不多說了,delegate是申明一個委託的關鍵詞,returnType是一個返回類型,delegateName是一個你給委託起的名字,你可以寫任何一個你喜歡的名字,paramtype param1…這個是參數列表。說了這么多可能看起來還是不是很好理解,我是這樣認為的,實用點來講,委託定義就是在一個函數定義中間加入一個delegate的關鍵詞。它的作用類似於你申明一個類:
public class ClassName {…}
創建一個委託的實例:
[public/protected/private] delegateName deleInstanceName = new delegateName(MethodName)
這個類似於實例化一個類,public ClassName instancename = new ClassName(…),這里有個要注意的地方,即MethodName方法要和delegateName的簽名一致。什麼是簽名一致,就是說MethodName的參數列表,返回值要分別和returnType、(paramtype param1,…)一致。舉個例子來說明下:
public delegate string DelegateDemo(string name, int age);
比如我們如上定義了一個委託,就寫法來說,其實就是在函數 string DelegateDemo(string name, int age)前面加了一個delegate的關鍵字,下面我們來用創建一個函數:
public string AgentDemo(string name, int age)
{
string rev = 「」;

return rev;
}
這個函數是做參數傳遞給一個DelegateDemo實例的,接下來創建一個DelegateDemo的實例:
DelegateName instanceDemo = new DelegateName(AgentDemo);
這時要說到一致了,即AgentDemo和聲明委託時的DelegateDemo(我們姑且將delegate去掉)這兩個函數的返回值,參數列表要相同。終於說完了,不知道看的人明不明白。
接下來,我們可以使用這個委託了(調用一個委託),如下:
string name = 「cshape」;
int age = 20;
instanceDemo(name, age);
當instanceDemo執行時,會執行AgentDemo函數,instanceDemo相當於C里的一個函數指針,現在這個指針指向AgentDemo的函數入口地址。
2.多點委託
前面提到的委託都只包含對一個方法的調用,如果需要調用多個方法,需要多次顯示的調用這個委託,我們還有另的選擇,我們可以讓一個委託中包含多個方法,這樣我們一次顯示調用委託,就可以按照順序連續的調用多個方法。看下面的例子:
public delegate void MultiDelegate(string name);
public void AgentDemo1(string str)
{
Console.WriteLine(str + 「this is AgentDemo1\n」);
}

public void AgentDemo2(string s)
{
Console.WriteLine(s + 「this is AgentDemo2\n」);
}

MultiDelegate multiDemo = new MultiDelegate(AgentDemo1);
multiDemo += new MultiDelegate(AgentDemo2);
multiDemo(「multiDemo test :」);

輸出的結果應該是:
multiDemo test :this is AgentDemo1
mutliDemo test :this is AgentDemo2

可以看到我們一次顯示的調用一個委託,它順序的(按照你添加方法的順序)執行了方法AgentDemo1和AgentDemo2。這里要注意的有幾點:
● 委託支持 +=,-=這樣的運算符,對應為添加或去掉一個方法
● 多點委託不可以定義有返回值,因為無法處理多個方法的返回值,所以如果要使用多點委託,應該用void,否則你的編譯會返回一個錯誤
● 多點委託不建議你的參數列表中有OUT的類型,這樣只會out最後一個方法的值,其他的值會丟失。
3.委託的理解
首先申明,這只是我舉的一個例子,目的是幫助理解委託的過程,其中很多地方都經不起推敲,望大家知悉。言歸正傳,
你想要吃飯,
但是自己又不會做(委託方不知道實現細節),
你計劃找個飯店,叫個回鍋肉飯(定義了一個委託)
你決定找常去的那家叫做A的飯店(實例化一個委託)
你打電話給A飯店(委託調用)
A飯店給你做好了你的回鍋肉飯(代理函數工作)
飯來了,真好。

4.委託的使用時機
當你需要把一個方法傳送給其他方法時,可以考慮使用委託。好像不是很好理解,也可以這樣說,當你確定要處理一件事,但又不能確定處理方法時,可以考慮用委託。其實單獨的說委託的應用好像有點牽強,委託更多的是在事件中的應用。
5.一個委託的例子
我用兩個類來做這個例子,一個類,我稱它為委託方,一個類我稱它為代理方,代碼如下:
using System;

namespace Visen.Demo.Delegate
{
///<summary>
/// StartUp 委託演示中的程序入口,含委託方。
///</summary>
class StartUp
{
#region公用的方法

#region應用程序的主入口點。
///<summary>
///應用程序的主入口點。
///</summary>
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("This is a delegate demo\n");

Visen.Demo.Delegate.Agent ag = new Agent();

//定義一個委託類型的對象
OutMessage singleDele = new OutMessage(ag.ShowMessage);
OutMessage deleStaticMeth = new OutMessage(Agent.SShowMessage);

//定義一個多點委託
OutMessage MultiDele = new OutMessage(ag.ShowMessage);
MultiDele += new OutMessage(Agent.SShowMessage);

singleDele(" delegate instance singleDele");
deleStaticMeth(" delegate instance deleStaticMeth");
MultiDele(" this is a MultiDele");
Console.Read();
}
#endregion應用程序的主入口點。

#endregion公用的方法

#region私用的欄位
///<summary>
///定義一個委託類型
///</summary>
private delegate void OutMessage(string msg);
#endregion私有的欄位
}
}

下面是代理方:
using System;

namespace Visen.Demo.Delegate
{
///<summary>
/// Agent 類為委託者的代理方,處理委託者委託的事務。
///</summary>
public class Agent
{
#region公用的方法

#region空的構造函數
///<summary>
///空的構造函數
///</summary>
public Agent()
{
}
#endregion空的構造函數

#region顯示一條信息到控制台,一個類成員函數作為代理方
///<summary>
///顯示一條信息到控制台,一個類成員函數作為代理方
///</summary>
///<param name="msg">顯示內容</param>
public void ShowMessage(string msg)
{
Console.WriteLine("Method ShowMessage out:" + msg + "\n");
}
#endregion顯示一條信息到控制台,一個類成員函數作為代理方

#region顯示一條信息到控制台,一個類靜態函數作為代理方
///<summary>
///顯示一條信息到控制台,一個類靜態函數作為代理方
///</summary>
///<param name="msg">顯示信息</param>
public static void SShowMessage(string msg)
{
Console.WriteLine("static Method SShowMessage out:" + msg + "\n");
}
#endregion顯示一條信息到控制台,一個類靜態函數作為代理方

#endregion公用的方法
}
}
輸出為:
This is a delegate demo

Method ShowMessage out: delegate instance singleDele

static Method SShowMessage out: delegate instance deleStaticMeth

Method ShowMessage out: this is a MultiDele

static Method SShowMessage out: this is a MultiDele

可見:方法函數可以是類成員函數,也可以是一個靜態成員,只要和委託的簽名相同就可以了。

有錯的地方,請大家批評指正,謝謝!

I. C#中的委託是什麼怎樣使用書上的我看不太明白呀,教我一下

這個的確不好理解 說簡單點 打個比方就好像按鈕的click事件 我們(再.net中)寫按鈕的事件都事雙擊按鈕 再後台就會自動生成一個按鈕的click函數,然後我們就再這個函數裡面寫該按鈕要作的事。其實這就是個委託加事件,委託起的作用就事再把這個事件個這個click函數聯系起來。再asp.net中我們會看到這樣的例子
this.Button1.Click += new System.EventHandler(this.Button1_Click);這個就是委託。至於具體使用方法 這個不好說 你自己去琢磨。關鍵是要理解委託能作什麼

閱讀全文

與C委託鏈上的方法如何執行相關的資料

熱點內容
真假海螺肉的鑒別方法 瀏覽:771
鬍子有點黃用什麼方法洗 瀏覽:246
安卓手機亮屏時間哪裡設置方法 瀏覽:358
激光筆的使用方法 瀏覽:625
架接果樹方法視頻 瀏覽:685
名師閱讀教學方法 瀏覽:759
長發快速剪發方法視頻 瀏覽:74
銅絲球連接方法 瀏覽:42
駁口金油使用方法 瀏覽:858
足背伸的鍛煉方法 瀏覽:794
牛舍風機安裝方法 瀏覽:392
道路綠地覆蓋率的計算方法 瀏覽:766
做木珠子最簡單的方法 瀏覽:396
燈光控制手機的使用方法 瀏覽:83
目的基因檢測的步驟和方法是什麼 瀏覽:678
分數混合計算方法總結 瀏覽:374
英語教學方法有哪些直接法情景法 瀏覽:929
分析和綜合思維方法的運用 瀏覽:784
aca電蒸鍋使用方法 瀏覽:854
畫疊被子的簡便方法 瀏覽:363