精通c# -- 委託

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);

如果我們沒有把委託成員變量定義為私有的,調用者就可以直接訪問委託對象。這樣調用者就可以把變量重新賦值為新的委託對象(也就是修改了當前調用的方法列表),也可以直接調用委託的調用列表。


分享到:


相關文章: