本文使用bubble sort的sample code來解釋delegate的用法,sample code 如下
using System;
namespace BubbleSort
{
public delegate bool ComparisonHandler(int first, int second);
class Program
{
static void Main(string[] args)
{
int[] numberList = { 3, 1, 5, 9, 7 };
int[] orderedNumberList = CompareMethod.compare(numberList, CompareType.smallerCompare);
foreach (int number in orderedNumberList)
{
Console.Write("{0} ", number);
}
Console.ReadKey();
}
}
class CompareMethod
{
public static int[] compare(int[] compareNumberList, ComparisonHandler comparisonMethod)
{
int i, j, temp;
for (i = compareNumberList.Length - 1; i >= 0; i--)
{
for (j = 0; j < i; j++)
{
if (comparisonMethod(compareNumberList[j], compareNumberList[i]))
{
temp = compareNumberList[i];
compareNumberList[i] = compareNumberList[j];
compareNumberList[j] = temp;
}
}
}
return compareNumberList;
}
}
class CompareType
{
public static bool biggerCompare(int firstNumber, int secondNumber)
{
return firstNumber > secondNumber;
}
public static bool smallerCompare(int firstNumber, int secondNumber)
{
return firstNumber < secondNumber;
}
}
}
和delegate有關的程式碼,已經用橘色的區塊標記了
整個程式碼是把進行比對的流程動作寫在CompareMethod.compare()方法內,而比對的原則則是另外寫在CompareType的類裡,裡面有包含了biggerCompare()及smallerCompare()二個方法,如果你要由小排到大,就要用biggerCompare(),由大到小,就用smallerCompare().
橘色的第二個區那行,就是要把numberList這個數字陣列傳給CompareMethod.compare()進行比對排序,那除了數字陣列外,我們還要告訴CompareMethod.compare()是要由大到小,還是由小到大,所以第二個參數就傳送CompareType.smallerCompare.
但是你這樣傳編譯器是不認得的,所以我們要使用delegate,delegate說穿了就是一種用來表示方法的型態,所以我們加了第一個橘色區塊,宣告了一個delegate.
這個宣告你要注意幾件事,名稱不重要,但是delegate的返回類型和參數數量及參數類型,要和想要傳送的方法完全相同.
比如delegate宣告返回bool,有二個參數都是int類型,就和我們要傳送的smallerCompare()是完全相同的.
完成delegate宣告後,你就可以傳送方法了.
而第三個橘色區塊就是接收端,你可以看到它的參數類型就是我們宣告的ComparisonHandler,至於comparisonMethod是實例名稱隨便你取.
第四個橘色區塊就是利用delegate的實例傳送參數到smallerCompare進行比對並返回bool值,來決定排序位置前後.
這樣我們就完成了delegate的使用了.
那為什麼要寫得那麼多個class呢??
因為如果我要增加新的排序方法,那我只要在compareType裡加一個新方法,其他的部分就不用去更動,這樣是比較有利於維護