前言:
1.委托是一個類,定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞。
把一個 參數類型 返回值 相同 方法名不同 的方法當變量 的方法 叫委托。
為了實現程序的六大設計中的開閉原則:解耦,對修改關閉,對擴展開放。邏輯分離。
直接調用函數和使用委托調用函數的區別就是是否方便對外擴展。
當我們窗體傳值、線程啟動時綁定方法、lambda表達式、異步等等情況下需要用到。
2.事件是一種特殊的委托,本質就是委托,事件是回調機制的一種應用。
當委托調用的函數達到某種條件時,可以通過回調通知調用者。
一:委托的申明
1. delegate ,至少0個參數,至多32個參數,可以無返回值,可以指定返回值類型
eg: public delegate int MethodDelegate(int x,int y); //兩個參數,返回int類型
2. Action ,至少0個參數,無返回值的泛型委托
Action<int,string,bool> ,有傳入int、string、bool類型的參數,無返回值的委托
eg: public void Test<Test>(Action<T> action,T p) { actoin(p); }
3. Func ,至少0個參數,至多16個參數,必須有返回值的泛型委托
Func<object,string,int> ,傳入參數為object、string類型的參數,返回值為int的委托
eg: public int Test<T1, T2>(Func<T1, T2, int>func,T1 a,T2 b){ return func(a, b); }
4.Predicate ,有且只有一個參數,返回值只為 bool 類型
predicate<int> 表示傳入為int類型的參數,返回bool類型的委托。
eg: public delegate bool Predicate<T>(T obj)
二:委托的使用
1. delegate
public delegate int MethodDelegate(int x,int y); private static MethodDelegate method; static void Main(string[] args) { method = new MethodDelegate(Add); method(10,20); } private static int Add(int x, int y) { return x +y; }
2. Action
static void Main(string[] args) { Test<string>(Action, "Hello World"); Test<string>(p => { Console.WriteLine("{0}", p); }, "Hello World" ); } public static void Action(string s) { Console.WriteLine(s); } public static void Test<T>(Action<T> action,T p) { action(p); }
3. Func的使用
static void Main(string[] args) { Test<int, int>(Fun, 100, 200); } public static int Test <T1, T2>(Func<T1, T2, int>func, T1 a,T2 b) { return func(a ,b); } private static int Fun(int a ,int b) { return a + b; }
4. predicate 的使用
static void Main(string[] args) { Point[] points = { new Point(100,200) , new Point(250,375), new Point(150,250), new Point(275,395), new Point(295,450) }; Point first = Array.Find(points,ProductGT10) ; Console.WriteLine("Found: X = {0},Y = {1}", frist.x, frist.Y); } private static bool ProductGT10(Point p) { if(p.X * p.Y > 100000) { return true; } else { return false; } }
三:委托的清空
1.在類中循環去除委托引用
public MethodDelegate OnDelegate; public void ClearDelegate() { while(this.OnDelegate != null) { this.OnDelegate -= this.OnDelegate; } }
2.在方法中查詢出委托后去除
public MethodDelegate OnDelegate; static void Main(string[] args) { Program test = new Program(); if(test.OnDelegate != null) { System.Delegate[] dels = test.OnDelegate.GetInvocationList(); for(int 1 = 0; i < dels.Length; i++) { test.OnDelegate -= dels[i] as MethodDelegate; } } }
PS:下面三種方式屬於老式委托的使用,就不要用了。C#3.5之后都用 Action Func
WithParaNoReturnEventHandler _WithParaNoReturnEventHandler = new WithParaNoReturnEventHandler(MyDelegate.SayChinese); MyDelegate.Say("張三",_WithParaNoReturnEventHandler); //C#1.0 傳統調用 MyDelegate.Say("張三", delegate(string name) { Console.WriteLine("你好," + name); }); //C#2.0 匿名方法 MyDelegate.Say("張三", (name) => { Console.WriteLine("你好," + name); }); //C#3.0 lambda表達式