什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...
什麼是委托?
委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組;
1.實例化委托的方式:
方式1:通過new創建實例:
public delegate void ShowDelegate(); 或者 public delegate string ShowDelegate(string str);
ShowDelegate d = new ShowDelegate();
方式2:使用賦值的方式:
ShowDelegate s = test.show;
方式3:匿名委托
ShowDelegate s = delegate(){ console.WriteLine("匿名委托");}
2.使用委托
方式1:直接調用委托的變數,如:showDelegate("s",1);
方式2:invoke(),如showDelegate.invoke("s",2); //執行方法,如果委托定義沒有參數,則invoke也沒有參數,委托沒有返回值,則invoke也沒有返回值;
//BeginInvoke,開啟一個線程去執行委托,netCore不支持,netframeWork支持,NetCore有更好的多線程功能來支持;
3.多播委托(委托鏈)
1)委托都是繼承自MulicastDelegate(多播委托),定義的委托基本上都是多播委托;
2)可以通過+=把多個方法添加到這個委托中,形成一個執行鏈,按照添加的先後順序依次執行;
3)可以通過-=把加入到委托的方法註銷,
4)action.BeginInvoke()會開啟一個新的線程去執行委托,註冊多個委托時,不能使用beginInvoke()去執行;
5)註冊有多個方法的委托想要開啟新線程去執行委托,可以通過action.GetInvocationList()獲取到所有的委托,然後迴圈執行,每個方法執行都可以用BeginInvoke;
4.多播委托使用的問題:
1)使用時,委托鏈的第一個方法報錯了,導致後面註冊的方法都是無法調用的,
解決方法:使用GetInvocationList按照調用順序返回此多播委托調用的列表;
2)當委托鏈上,註冊的都是有返回值的方法時,如果調用委托,那麼只會返回最後一個註冊的方法的返回值;
5.委托判斷
在使用Invoke的時候:判斷調用的委托是否為空,如果為空,不執行,不為空執行;
Delegate s = Show;
s -=Show;
s?.Invoke();
6.為什麼使用委托:
1)委托時一種引用類型,表示對具體特定參數列表和返回類型的方法的引用,與C或者C++中的函數指針不同,
委托是一種面向對象,並且是類型安全的;
2)委托可以實現代碼的重用,邏輯解耦,在方便代碼維護的同時,方法聲明和方法實現分離,也可提升程式的可擴展性;
7.泛型委托:與普通委托一樣
public delegate void ShowDelegate<T,S>(T t,S s);
C#2.0提供了Action和Func兩個泛型委托,不用申明,直接可用;
1)Action
public class ActionTest{
public Action Action;
public void SendMsg(){
console.writeline("消息發送完成!");
}
public void Test(){
//實例化方式有四種:
action = SendMsg;
action = new Action(SendMsg);
action = delegate(){
console.writeLine("delegate方式") //C#2.0提出用匿名函數代替;
}
action = ()=>{
console.writeLine("lambda 匿名方法") //C#3.0提出用lamda表達式寫
}
action();
action.Invoke();
}
}
2)Func與Action寫法類似;
8.什麼是事件
1)事件是基於委托的,為委托提供一個訂閱或發佈的機制,是一種特殊的委托,調用事件和委托是一樣;
public event DoDelegate DoEvent;
9.委托與事件的區別?
1)事件只能在方法的外部進行聲明,而委托內外部都可以;
2)事件只能在類的內部進行觸發,不能在類的外部進行觸發,而委托在類的內外部都可以觸發;
3)委托一般是用於回調,而事件一般是用於外部介面;