在C#中使用一個類時,分兩個階段。首先需要定義這個類,即告訴編譯器這個類由什麼字段和方法組成。然後(除非只使用靜態方法)實例化類的一個對象。使用委托時,也需要經過這兩個步驟。首先定義要使用的委托,對於委托,定義它就是告訴編譯器這種類型代表了那種類型的方法,然後創建該委托的一個或多個實例。
定義委托是從delegate開始的然而它是如何運作的呢。也許弄個鼠標事件會容易理解一些,這裡還是拿出例子來。
using System;
namespace Wrox.ProfCSharp.AdvancedCSharp
{
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)};
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]))
{
object temp = sortArray[i];
sortArray[i] = sortArray[j];
sortArray[j] = temp;
}
}
}
}
}
}
代碼中,首先聲明了一個delegate bool CompareOp(object lhs, object rhs)委托,再說說委托:
委托機制是促使事件發送與事件接受的一種對接策略,對象對周圍信號的反應或在一定環境中所具備的對其它對象的通知行為的響應則被描述成所謂的“事件”,這可以類比人對周圍世界反饋產生信號的能力。委托就是一種定向信號流:指定產生、接受信號者並產生信號反饋的技術。那麼這段委托是怎麼把程序連動起來的呢,看後面的代碼。
首先是CompareOp employeeCompareOp = new CompareOp(Employee.RhsIsGreater)這裡就象定義了一個監聽裝置,一旦發生了CompareOp(object lhs, object rhs)這個事件就去執行Employee.RhsIsGreater的代碼。
接下來我們就去看看Employee.RhsIsGreater裡面的東西。
public static bool RhsIsGreater(object lhs, object rhs)
{
Employee empLhs = (Employee) lhs;
Employee empRhs = (Employee) rhs;
return (empRhs.salary > empLhs.salary) ? true : false;
}
public static bool RhsIsGreater(object lhs, object rhs)
{
Employee empLhs = (Employee) lhs;
Employee empRhs = (Employee) rhs;
return (empRhs.salary > empLhs.salary) ? true : false;
}
也就是說RhsIsGreater的參數是匹配CompareOp存在的,參數中沒有直接使用Employee這個type而是采用了一種通用的做法,全都弄成object需要的時候再做轉換,暫時還無法理解其深遠的意義,先記著了。估計是定義委托時不能用這些自定義的type吧。
那麼這段代碼是什麼時候運行的呢,注意看這段
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]))
{
object temp = sortArray[i];
sortArray[i] = sortArray[j];
sortArray[j] = temp;
}
}
}
}
其中static public void Sort(object [] sortArray, CompareOp gtMethod)的參數裡就有這種我們委托好的CompareOp了。也就是說一旦運行到if (gtMethod(sortArray[j], sortArray[i]))系統就會去找CompareOp employeeCompareOp = new CompareOp(Employee.RhsIsGreater);然後找public static bool RhsIsGreater(object lhs, object rhs)這樣就執行到裡面的代碼了。
整個事件響應完成。
using System;
namespace Wrox.ProfCSharp.AdvancedCSharp
{
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)};
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]))
{
object temp = sortArray[i];
sortArray[i] = sortArray[j];
sortArray[j] = temp;
}
}
}
}
}
}