委派是型別安全的函數包裝物件。宣告語法類似函數簽章,前加 delegate 關鍵字:
delegate int Del(int value); // 可包裝 int->int 的靜態/實例方法
ref struct A { static int Square(int i) { return i*i; } };
ref struct B { int Cube(int i) { return i*i*i; } };
Del^ d = gcnew Del(&A::Square); // 靜態方法
Console::WriteLine(d(10)); // 100
B^ b = gcnew B;
d = gcnew Del(b, &B::Cube); // 實例方法:傳實例控制碼 + 方法指標
Console::WriteLine(d(10)); // 1000
若委派為 nullptr 呼叫會拋 NullReferenceException。
使用 +=、-= 組合/移除目標方法,呼叫時依序執行,回傳值為最後一個目標的回傳值:
d += gcnew Del(&A::Square);
d += gcnew Del(b, &B::Cube);
int result = d(3); // 先 Square(3)=9,再 Cube(3)=27,result=27
delegate int Comparer(int x, int y);
int Ascending(int x, int y) { return x - y; }
int Descending(int x, int y) { return y - x; }
void Sort(array^ arr, Comparer^ cmp) {
// 簡易氣泡排序,使用 cmp 決定順序
for (int i=arr->Length-1; i>0; --i)
for (int j=0; j 0) {
int t = arr[j]; arr[j] = arr[j+1]; arr[j+1] = t;
}
}
int main() {
array^ a = {5,2,8,1};
Sort(a, gcnew Comparer(Ascending)); // 1,2,5,8
Sort(a, gcnew Comparer(Descending)); // 8,5,2,1
}
事件是委派的受限公開介面:外部只能 +=/-=,不能直接呼叫或清空:
ref class Counter {
int value;
event EventHandler^ Changed; // EventHandler = delegate void(Object^, EventArgs^)
public:
property int Value {
int get() { return value; }
void set(int v) {
if (value != v) {
value = v;
if (Changed != nullptr) Changed(this, EventArgs::Empty);
}
}
}
};
void OnChanged(Object^ sender, EventArgs^ e) {
Console::WriteLine("Value changed to {0}", safe_cast(sender)->Value);
}
int main() {
Counter^ c = gcnew Counter;
c->Changed += gcnew EventHandler(OnChanged);
c->Value = 10; // 觸發事件
}
| 特性 | 委派 | 事件 |
|---|---|---|
| 外部可呼叫 | 是 | 否 |
| 外部可指派 (=) | 是 | 否(只能 +=/-=) |
| 用途 | 回呼、策略、非同步 | 通知、觀察者模式 |