C# Delegate 委托(上)
Delegate(委托):
C# 中的委托(Delegate)類似 C++ 中的 Function Pointer。 常用於事件和回調方法。所有的委托(Delegate)都衍生自 System.Delegate。
1. 宣告委託:
delegate void IntMethodInvoker(int x);
宣告時需包含回傳和引入之型別。
也可以使用訪問修飾符例如:
public delegate void IntMethodInvoker(int x);
2. 委託的使用:
using System; namespace DotNetCoreTest { class Program { // 宣告委托 public delegate void Greeting(); public static void Hello() { Console.WriteLine("Hello"); } static void Main(string[] args) { // 用 Hello 實體化 Greet Greeting Greet = new Greeting(Hello); Greet(); Greet.Invoke(); } } }
執行結果:
Hello Hello
呼叫 Greet() 等同於呼叫 Greet.Invoke()
3. Func<T> 和 Action<T> 委托:
Func<T>委托用於委托有回傳值的方法,Action<T> 委托用於委托無回傳值的方法
Action<T>委托的用法:
using System; namespace DotNetCoreTest { class Program { public static void Hello (string name) { Console.WriteLine($"Hello {name}"); } static void Main(string[] args) { Action<string> Greet = Hello; Greet("Bob"); Greet.Invoke("Alice"); } } }
Func<T>委托的用法:
using System; namespace DotNetCoreTest { class Program { public static int DoubleNum (int num) { return 2 * num; } static void Main(string[] args) { Func<int, int> DN = DoubleNum; Console.WriteLine($"{DN (20)}"); Console.WriteLine($"{DN.Invoke (20)}"); } } }
4. Func<T> 委托陣列:
Func<T> 和 Action<T> 可以衍伸出一些奇怪的寫法例如委托陣列:
using System; namespace DotNetCoreTest { class Program { public static int DoubleNum(int num) { return 2 * num; } public static int AddOne(int num) { return num + 1; } static void Main(string[] args) { Func<int, int>[] MathOps = { DoubleNum, AddOne }; Console.WriteLine(MathOps[0](10)); Console.WriteLine(MathOps[1](10)); } } }
5. Func<T> 委托作為參數:
這應該是目前最實用的功能
using System; namespace DotNetCoreTest { class Program { public static int DoubleNum(int num) { return 2 * num; } public static int DoSomeMath(Func<int, int>MathOp, int num) { return MathOp(num); } static void Main(string[] args) { Console.WriteLine($"{DoSomeMath(DoubleNum, 10)}"); } } }
!!! 6. 多播委托: !!!
這應該是最值得注意的功能,我們能用 "+" 號來合併多個委托、"-" 號來刪除委托。 呼叫多播委托時會將參數一一傳播給多個委托:
using System; namespace DotNetCoreTest { class Program { public static void Hello(string name) { Console.WriteLine($"Hello {name}"); } public static void Hi (string name) { Console.WriteLine($"Hi {name}"); } static void Main(string[] args) { Action<string> Greet = Hello; Greet += Hi; Greet("Bob"); } } }
執行結果如下:
Hello Bob Hi Bob
!!! 呼叫多播委托時的注意事項: !!!
- 調用方法的順序和添加的順序無關
- 其中一的方法發生異常時會造成迭代停止
留言
張貼留言