最近要因為要使用到多線程,經常要把一些方法封起來,給線程去執行,剛開始的時候,根據自己之前學的C#知識,去創建一些委托,然后把方法作為參數傳遞給其中一個方法的線程去執行,每次都要new一些委托,實在是煩,其實知道有一些簡便的方法去做的(比如使用Action和匿名方法以及lambda 表達式),但本人有點懶,本想能自己自定義 委托就自定義委托去實現唄,最后由於越來越多這樣情況出現,就干脆好好去看看Action和匿名方法以及lambda 表達式,怎么才能更方便的去實現方法的傳遞!廢話不多說,先逐一溫習一下概念,講解過程中,有錯誤歡迎指出!
Action 委托:
概念:封裝一個方法,該方法不具有參數並且不返回值。
可以使用此委托以參數形式傳遞方法,而不用顯式聲明自定義的委托。 封裝的方法必須與此委托定義的方法簽名相對應。 也就是說,封裝的方法不得具有參數,並且不得返回值,說簡淺一點就是,當你需要去定義一個不需要參數並且不需要返回值的委托時,微軟不用我們去自己去定義,可以用Action代替你定義的委托(如果你需要傳遞參數可以用Action<T>,如果你需要參數也需要返回值可以用Func<T,TResult>,大家可以自己去了解一下! ).
平常我們要使用委托的時候,需要自定義委托,然后把符合的方法賦值給委托,讓委托去執行,例如以下代碼顯式聲明了一個名為 ShowValue 的委托,並將對 Name.DisplayToWindow 實例方法的引用分配給其委托實例:
using System; using System.Windows.Forms; public delegate void ShowValue(); public class Name { private string instanceName; public Name(string name) { this.instanceName = name; } public void DisplayToConsole() { Console.WriteLine(this.instanceName); } public void DisplayToWindow() { MessageBox.Show(this.instanceName); } } public class testTestDelegate { public static void Main() { Name testName = new Name("Koani"); ShowValue showMethod = testName.DisplayToWindow; showMethod(); } }
這是平常我們自定義委托去執行一個方法,這樣雖然清晰明了,但是卻是麻煩,每次都得根據方法簽名去自定義一些委托,增加代碼系統開銷啊,寫多了也累!那
用Action看看,方便點不!
下面請看一個使用Action的例子,簡化了此代碼,它所用的方法是實例化 Action 委托,而不是顯式定義一個新委托並將命名方法分配給該委托!
using System; using System.Windows.Forms; public class Name { private string instanceName; public Name(string name) { this.instanceName = name; } public void DisplayToConsole() { Console.WriteLine(this.instanceName); } public void DisplayToWindow() { MessageBox.Show(this.instanceName); } } public class testTestDelegate { public static void Main() { Name testName = new Name("Koani"); Action showMethod = testName.DisplayToWindow; showMethod(); } }
有了action之后直接上,省得去自定義委托了,方便了許多,明白action的好處了吧!
匿名方法:
概念:匿名方法,顧名思義就是沒有名稱的方法!
在 2.0 之前的 C# 版本中,聲明委托的唯一方法是使用命名方法。 C# 2.0 引入了匿名方法,主要是您可使用匿名方法來忽略參數列表。這意味着匿名方法可轉換為具有各種簽名的委托,通過使用匿名方法,由於您不必創建單獨的方法,因此減少了實例化委托所需的編碼系統開銷!
要將代碼塊傳遞為委托參數,創建匿名方法則是唯一的方法!請看下面示例:
//示例1,用匿名方法直接傳遞給按鈕的點擊事件去執行,不用去實例一個方法了 button1.Click += delegate(System.Object o, System.EventArgs e) { System.Windows.Forms.MessageBox.Show("Click!"); }; //示例2,直接將匿名方法賦給委托,當然你也可以用上面我說的Action去接收匿名方法,這里只是為了方便去說明 delegate void Del(int x); Del d = delegate(int k) { /* ... */ };
有了匿名方法,是不是方便點了,要執行什么代碼,直接用匿名方法去封裝,不用去實例一個新的方法,這種用法,在多線程下使用起來更加方便,例如:
void StartThread() { System.Threading.Thread t1 = new System.Threading.Thread (delegate() { System.Console.Write("Hello, "); System.Console.WriteLine("World!"); }); t1.Start(); }
如果創建方法所需的系統開銷是不必要的,則指定代碼塊(而不是委托)可能非常有用。 啟動新線程即是一個很好的示例。 無需為委托創建更多方法,線程類即可創建一個線程並且包含該線程執行的代碼。上示例,里面線程的參數是一個無參數的委托(類似action),所以直接傳遞無參數的匿名方法進去就行了!無需自己再去定義委托之類!
Lambda 表達式:
看官方對lambda表達式的解析!
Lambda 表達式是一種可用於創建委托或表達式目錄樹類型的匿名函數。 通過使用 lambda 表達式,可以寫入可作為參數傳遞或作為函數調用值返回的本地函數。 Lambda 表達式對於編寫 LINQ 查詢表達式特別有用。
是不是,看着一頭霧水,不錯,我也是,官方的東西總是文縐縐的,簡單來說簡化了匿名函數的使用,讓你讓代碼更加簡潔,優雅,用運算符 " => "表示,左邊指定輸入
參數,右邊是lambda的主體!
lambda表達式:
1.一個參數:param=>expr
看示例:
delegate int del(int i); static void Main(string[] args) { del myDelegate = x => x * x; int j = myDelegate(5); //j = 25 }
這是lambda表達式的表示,注意:只有一個輸入參數時,括號才是可選的;否則括號是必需的。 括號內的兩個或更多輸入參數使用逗號加以分隔。
2.多個參數:(param-list)=>expr
//示例1 (x, y) => x == y //示例2 (x,y,z) => SomeMethod();
lambda表達式也是可以和action結合進行使用,例如:
using System; using System.Windows.Forms; public class Name { private string instanceName; public Name(string name) { this.instanceName = name; } public void DisplayToConsole() { Console.WriteLine(this.instanceName); } public void DisplayToWindow() { MessageBox.Show(this.instanceName); } } public class LambdaExpression { public static void Main() { Name testName = new Name("Koani"); //此處是lambda表達式和action結合 Action showMethod = () => testName.DisplayToWindow(); showMethod(); } }
Lambda 的一般規則如下:
-
Lambda 包含的參數數量必須與委托類型包含的參數數量相同。
-
Lambda 中的每個輸入參數必須都能夠隱式轉換為其對應的委托參數。
-
Lambda 的返回值(如果有)必須能夠隱式轉換為委托的返回類型。
(有問題,大家多少交流836911886,加我請記得說:博客園)