委托(Daelegate)delegate是C#中的一種類型,它實際上是一個能夠持有對某個方法的引用的類。與其它的類不同,delegate類能夠擁有一個簽名(signature),并且它只能持有與它的簽名相匹配的方法的引用。它所實現的功能與C/C++中的函數指針十分相似。它允許你傳遞一個類A的方法m給另一個類B的對象,使得類B的對象能夠調用這個方法m。但與函數指針相比,delegate有許多函數指針不具備的優點。首先,函數指針只能指向靜態函數,而delegate既可以引用靜態函數,又可以引用非靜態成員函數。在引用非靜態成員函數時,delegate不但保存了對此函數入口指針的引用,而且還保存了調用此函數的類實例的引用。其次,與函數指針相比,delegate是面向對象、類型安全、可靠的受控(managed)對象。也就是說,runtime能夠保證delegate指向一個有效的方法,你無須擔心delegate會指向無效地址或者越界地址。
實現一個delegate是很簡單的,通過以下3個步驟即可實現一個delegate:
step1.聲明一個delegate類型,它應當與你想要傳遞的方法具有相同的參數和返回值類型。
step2.創建delegate對象,并將你想要傳遞的函數作為參數傳入。
step3.在要實現異步調用的地方,通過上一步創建的對象來調用方法。
下面是一個簡單的例子:
using System;

namespace MyApp


{

/**////
/// MyDelegateTest 的摘要說明。
///
public class MyDelegateTest

{
// 步驟1,聲明delegate類型
public delegate void MyDelegate(string name);

// 這是我們欲傳遞的方法,它與MyDelegate具有相同的參數和返回值類型
public static void MyDelegateFunc(string name)

{
Console.WriteLine("靜態方法: Hello, {0}", name);
}

public static void Main()

{
// 步驟2,創建delegate對象
MyDelegate md = new MyDelegate(MyDelegateTest.MyDelegateFunc);

// 步驟3,調用delegate
md("王銘");

//如何調用類成員方法
myclass mc=new myclass();
md=new MyDelegate(mc.mymethod);
md("Wang Ming");

//委托可以作為方法的參數
WL(md);

Console.ReadLine(); //為了顯示控制臺
}

public static void WL(MyDelegate mywl)

{
mywl("Ming Wang");
}


public MyDelegateTest()

{}
}

public class myclass

{
public void mymethod(string name)

{
Console.WriteLine("類成員方法: Hello,{0}",name);
}
}
}

下面是一個比較復雜的例子,使用委托技術,BubbleSorter.Sort方法可以排序任何數組,前提是數組成員類提供比較的方法,本例中Employee提供RhsIsGreater方法。
using System;

namespace Wrox.ProfCSharp.AdvancedCSharp


{
//步驟1 定義Delegated類型
delegate bool CompareOp(object lhs, object rhs);

class MainEntryPoint

{
static void Main()

{
Employee [] employees =

{
new Employee("Karli Watson", 20000),
new Employee("Bill Gates", 10000),
new Employee("Simon Robinson", 25000),
new Employee("Mortimer", (decimal)1000000.38),
new Employee("Arabel Jones", 23000),
new Employee("Avon from 'Blake's 7'", 50000)};
//步驟2 創建Delegate對象,傳入要調用的函數作為參數
CompareOp employeeCompareOp = new CompareOp(Employee.RhsIsGreater);
BubbleSorter.Sort(employees, employeeCompareOp);

for (int i=0 ; i<employees.Length ; i++)
Console.WriteLine(employees[i].ToString());
Console.ReadLine();
}
}

class Employee // : object

{
private string name;
private decimal salary;

public Employee(string name, decimal salary)

{
this.name = name;
this.salary = salary;
}

public override string ToString()

{
return string.Format(name + ", {0:C}", salary);
}

public static bool RhsIsGreater(object lhs, object rhs)

{
Employee empLhs = (Employee) lhs;
Employee empRhs = (Employee) rhs;
return (empRhs.salary > empLhs.salary) ? true : false;
}
}

class BubbleSorter

{
static public void Sort(object [] sortArray, CompareOp gtMethod)

{
for (int i=0 ; i<sortArray.Length ; i++)

{
for (int j=i+1 ; j<sortArray.Length ; j++)

{
if (gtMethod(sortArray[j], sortArray[i]))//調用Delegate

{
object temp = sortArray[i];
sortArray[i] = sortArray[j];
sortArray[j] = temp;
}
}
}
}
}
}