轉自:http://zhidao.baidu.com/link?url=xyEmK-9RCxUFgUPWbwTDp9kg3cdb-JRCG2V2oTTiPdHIZNI3BihhyGT_94ewNcz5PCvla_l6nsNyk8E5XoRa2a
Delegate類簡介
------------------------
名稱空間:System
程式集:mscorlib(在 mscorlib.dll 中)
委託(Delegate)類是一種資料結構,通過它可引用靜態方法或引用類例項及該類的例項方法。
以往的介面程式設計中我們應該都接觸過各種型別的事件驅動(event driven)的處理模式,
在這種模式裡,我們定義相應事件觸發的函式。
例如:
Button1 的 Click事件,我們可以編寫Button1_Click 或 Btn1Clicked等函式來做相應的驅動處理。
而事件與驅動函式的對應關係就是通過委託(Delegate)類來關聯的。
其實委託(Delegate)類這種資料結構有些類似於之前C/C++中的函式指標。
Delegate類一個簡單應用
------------------------
1.定義一個Delegate函式資料結構
2.定義Delegate將引用的靜態方法或引用類例項及該類的例項方法
3.Delegate資料變數指向例項方法
4.通過Delegate資料變數執行例項方法
A very basic example (TestClass.cs):
using System;
namespace MySample
{
class TestClass
{
//1.定義一個Delegate函式資料結構
public delegate void GoDelegate();
[STAThread]
static void Main(string[] args)
{
//3.Delegate資料變數指向例項方法
GoDelegate goDelegate = new GoDelegate( MyDelegateFunc);
//4.通過Delegate資料變數執行例項方法
goDelegate();
return;
}
//2.定義Delegate將引用的靜態方法或引用類例項及該類的例項方法
public static void MyDelegateFunc()
{
Console.WriteLine("delegate function...");
}
}
}
編譯執行結果:
# TestClass.exe
delegate function...
使用Delegate類和Override實現多型的比較
-----------------------------------------------
1.使用Delegate類的時候,下面的例子可以很清楚的說明。
1.1 首先定義一個動物基類(MyAnimalDelegateClass), 基類中有顯示屬性的(ShowAnimalType)的public方法。
並且在ShowAnimalType方法中呼叫Delegate引用的例項方法
1.2 定義獅子(LionDelegateClass)和馬(HorseDelegateClass)兩個子類。Delegate與各自的例項方法繫結
實現不同的屬性顯示(ShowAnimalType)方法。
////Delegate example (TestClass.cs):
using System;
namespace MySample
{
class TestClass
{
[STAThread]
static void Main(string[] args)
{
//獅子(LionDelegateClass)的屬性顯示(ShowAnimalType)方法呼叫
LionDelegateClass lionDelegate = new LionDelegateClass();
lionDelegate.ShowAnimalType("MySample");
//馬(HorseDelegateClass)的屬性顯示(ShowAnimalType)方法呼叫
HorseDelegateClass horseDelegate = new HorseDelegateClass();
horseDelegate.ShowAnimalType("MySample");
}
}
//動物基類(MyAnimalDelegateClass)
public class MyAnimalDelegateClass
{
//Delegate資料結構定義
public delegate void DelegateFunction(string strFuncName);
private DelegateFunction m_delegateFunction = null;
//Delegate型別的屬性
public DelegateFunction delegateFunction
{
get
{
return m_delegateFunction;
}
set
{
m_delegateFunction = value;
}
}
//屬性顯示(ShowAnimalType)方法
public void ShowAnimalType(string strFuncName)
{
if (delegateFunction != null)
{
object[] args = {strFuncName};
//呼叫Delegate引用的例項方法
delegateFunction.DynamicInvoke(args);
}
}
}
//獅子(LionDelegateClass)
public class LionDelegateClass:MyAnimalDelegateClass
{
public LionDelegateClass()
{
this.delegateFunction = new DelegateFunction(subFunction1);
}
//獅子(LionDelegateClass)例項方法的實裝
private void subFunction1(string strFuncName)
{
System.Console.WriteLine(
string.Format("[{0}]This is a lion....", strFuncName));
}
}
//馬(HorseDelegateClass)
public class HorseDelegateClass:MyAnimalDelegateClass
{
public HorseDelegateClass()
{
this.delegateFunction = new DelegateFunction(subFunction2);
}
//馬(HorseDelegateClass)例項方法的實裝
private void subFunction2(string strFuncName)
{
System.Console.WriteLine(
string.Format("[{0}]This is a horse....", strFuncName));
}
}
}
編譯執行結果:
# TestClass.exe
[MySample]This is a lion....
[MySample]This is a horse....
2.使用Override實裝的時候,參考下面的例子。
1.1 首先定義一個動物基類(AbstractAnimalNoDelegateClass), 基類中有顯示屬性的(ShowAnimalType)的public方法。
並且在ShowAnimalType方法中呼叫抽象方法(NoDelegateFunction)
1.2 定義獅子(LionNoDelegateClass)和馬(HorseNoDelegateClass)兩個子類。
子類中實裝抽象方法(NoDelegateFunction)
實現不同的屬性顯示(ShowAnimalType)方法。
////Override example (TestClass.cs):
using System;
namespace MySample
{
class TestClass
{
[STAThread]
static void Main(string[] args)
{
//獅子(LionNoDelegateClass )的屬性顯示(ShowAnimalType)方法呼叫
LionNoDelegateClass lionNoDelegate = new LionNoDelegateClass();
lionNoDelegate.ShowAnimalType("MySample");
//馬(HorseNoDelegateClass )的屬性顯示(ShowAnimalType)方法呼叫
HorseNoDelegateClass horseNoDelegate = new HorseNoDelegateClass();
horseNoDelegate.ShowAnimalType("MySample");
}
}
//動物基類(AbstractAnimalNoDelegateClass)
public abstract class AbstractAnimalNoDelegateClass
{
public void ShowAnimalType(string strFuncName)
{
//抽象方法(NoDelegateFunction)呼叫
NoDelegateFunction(strFuncName);
}
//在基類中定義抽象方法(NoDelegateFunction)
protected abstract void NoDelegateFunction(string strFuncName);
}
//獅子(LionNoDelegateClass )
public class LionNoDelegateClass:AbstractAnimalNoDelegateClass
{
// 子類中實裝抽象方法(NoDelegateFunction)
protected override void NoDelegateFunction(string strFuncName)
{
System.Console.WriteLine(
string.Format("[{0}]This is a lion....", strFuncName));
}
}
//馬(HorseNoDelegateClass )
public class HorseNoDelegateClass:AbstractAnimalNoDelegateClass
{
// 子類中實裝抽象方法(NoDelegateFunction)
protected override void NoDelegateFunction(string strFuncName)
{
System.Console.WriteLine(
string.Format("[{0}]This is a horse....", strFuncName));
}
}
}
編譯執行結果:
# TestClass.exe
[MySample]This is a lion....
[MySample]This is a horse....
3.比較Delegate和Override實裝方式
可以看出Delegate實裝方式中,相當於定義一個函式指標的成員變數。
通過把實裝函式的地址賦給該成員變數,實現同樣的方法,處理方式的不同。
而Override方式中,則是在父類中預先定義好介面,通過實裝的不同,
來實現同樣的方法,處理方式的不同。
Delegate實裝方式比較靈活,適合設計不是很完善的場合,便於修改。
Override方式封裝性好,相對比較安全。
MulticastDelegate 類的應用
---------------------------------
在C#中,委託(Delegate)類是多路委託,這就說可以同時指向多個處理函式,
並且可以按照委託的先後順序,執行相應的函式。
如下例:
using System;
namespace MySample
{
class TestClass
{
[STAThread]
static void Main(string[] args)
{
DogDelegateClass dogDelegate = new DogDelegateClass();
dogDelegate.ShowAnimalType("MySample");
}
public class MyAnimalDelegateClass
{
public delegate void DelegateFunction(string strFuncName);
private DelegateFunction m_delegateFunction = null;
public DelegateFunction delegateFunction
{
get
{
return m_delegateFunction;
}
set
{
m_delegateFunction = value;
}
}
public void ShowAnimalType(string strFuncName)
{
if (delegateFunction != null)
{
object[] args = {strFuncName};
delegateFunction.DynamicInvoke(args);
}
}
}
public class DogDelegateClass:MyAnimalDelegateClass
{
public DogDelegateClass()
{
//多路委託函式 設定
this.delegateFunction = new DelegateFunction(subFunction31);
this.delegateFunction += new DelegateFunction(subFunction32);
}
//委託函式1
private void subFunction31(string strFuncName)
{
System.Console.WriteLine(
string.Format("[{0}]This is a dog....", strFuncName));
}
//委託函式2
private void subFunction32(string strFuncName)
{
System.Console.WriteLine(
string.Format("[{0}]This is a nice dog....", strFuncName));
}
}
}
編譯執行結果:
# TestClass.exe
[MySample]This is a dog....
[MySample]This is a nice dog....