Delegate 委託類型用來定義和響應應用程序中的回調。
回調指的是可以作為參數傳遞給其他代碼的一段可執行代碼,普通代碼是高層(應用程序)調用低層(系統函數、庫函數),回調時則是低層函數調用高層函數。
.NET委託類型是一個類型安全的對象,指向可以以後調用的其他方法。.NET委託是內置支持多路廣播和異步調用的對象。它允許內存中的對象進行雙向對話。
我們可以在任何需要強類型委託的情況下指定一個代碼語句(以及傳入代碼語句的參數),它是類型安全的。
委託包含三個信息:1.他所調用的方法名稱;2.該方法的參數;3.該方法的返回值類型。
委託既可以指向靜態方法,也可以指向實例方法。運行時動態調用其指向的方法。委託自己不執行,只是指向一個方法讓其去執行。(需要實例化)
(例子: //委託(這個委託可以指向任意傳入兩個整數,返回一個整數的方法)
public delegate int daleAa(int a, int b);)
//使用委託,在實例的過程中傳入方法(AA是一個類,jia是一個加法方法),直接使用方法名而不需要實例化創建對象是因為.NET提供了方法組轉換。
daleAa da = new daleAa(AA.jia);
da(3, 4);
)
委託有三個核心的方法(CLR自動生成),Invoke(調用)用來以同步方式調用委託對象的每個方法,這裡的同步指的是指調用者必須等待調用完成後才繼續執行(應該是在後臺自動調用??),BeginInvoke(異步調用)和EndInvoke(結束調用)能夠在第二個執行線程上異步調用當前方法。
(例子: //這是單線程的操作(以線程阻塞做實驗)
Console.WriteLine("");
daleAa a1 = new daleAa(AA.jia2);
int we1 = a1(10, 80);
Console.WriteLine("90=" + we1);
//多線程操作(異步調用委託),jia2也是加法,裡面多一個線程阻塞
Console.WriteLine("");
daleAa a2 = new daleAa(AA.jia2);
//這兩個委託的方法都是CLR動態生成的
IAsyncResult ifs = a1.BeginInvoke(10, 80, null, null);
//Console.WriteLine("主線程幹別的事請,完成之後就需要等待次線程的完成,因為只有一句輸出代碼,所以效率並未提升");
while (!ifs.IsCompleted)
{
Console.WriteLine("用於判斷異步操作是否已完成");
Thread.Sleep(1000);
}
//接收返回的值,讓主線程偷走了一步
int we2 = a1.EndInvoke(ifs);
Console.WriteLine("90=" + we2);
)
(多路廣播)一個委託對象可以維護一個可調用的列表而不是單獨一個方法,給委託添加多個方法時,重載+=就可以(對委託對象使用+=操作符的時候,編譯器會將該問題轉換為一個對靜態Delegate.Combine()方法的調用,-=操作符也是被重載過的,在這裡是對Remove()的調用)。
(例子: //委託支持多路廣播
da += AA.jian;
//當一個委託同時被多個方法調用時會先後執行多次,也就是說,這一次會得到兩個值,先加的5+4=9,後減為5-4=1
da(5, 4);
//移除某個方法(此處為加法)
da -= AA.jia;
da(3, 8);
)
如果我們沒有把委託成員變量定義為私有的,調用者就可以直接訪問委託對象。這樣調用者就可以把變量重新賦值為新的委託對象(也就是修改了當前調用的方法列表),也可以直接調用委託的調用列表。
閱讀更多 一念花開1973 的文章