以前我們為了能夠調用一個方法,必須比照這個方法定義一個相應的delegate.
原先我們定義delegate
// 委托聲明 -- 定義一個簽名: delegate doubleMathAction(double num); class DelegateTest { // 符合委托聲明的常規方法 static double Double(double input) { return input * 2; } static void Main() { 原版: // 使用一個命名方法實例化委托類型 MathAction ma = Double; // 調用委托實例 double multByTwo = ma(4.5); Console.WriteLine(multByTwo); 簡化版1: // 再用匿名方法來實例化委托類型 MathAction ma2 = delegate(double input) { return input * input; }; double square = ma2(5); Console.WriteLine(square); 簡化版2: // 最後用Lambda表達式來實例化委托類型 MathAction ma3 = s => s * s * s; double cube = ma3(4.375); Console.WriteLine(cube); } }
這個是否能有更好的實現辦法呢?
答案是:肯定有了.也就是有通用的delegate了。在.NETFramework 3.5中,提供了兩類通用的delegate。
如果方法有返回值,則使用Func,或者Func<>
如果方法沒有返回值,則使用Action,或者Action<>
T
此委托封裝的方法的參數類型。
TR
此委托封裝的方法的返回值類型。
在使用 Func
使用Func<>委托,我們這樣寫
using System; public classLambdaExpression { public static void Main() { Funcconvert = s=> s.ToUpper();//該方法將小寫字母轉為大寫 string name = "Dakota"; Console.WriteLine(convert(name)); } }
Func委托是system下的全局函數,不用我們自定,系統自定義的,供我們使用,帶有多個重載.
這裡我們除了使用Func委托外,還是用了Labdab表達式.這裡我再談談這個表達式.
Lambda表達式的基礎類型是泛型 Func委托之一。 這樣能以參數形式傳遞
lambda表達式,而不用顯式將其分配給委托。 尤其是,因為 System.Linq命名空間中許多類型方法具有Func
下面一行代碼將生成一個序列,其中包含 numbers 數組中在 9左側的所有元素,因為它是序列中第一個不滿足條件的數字:
int[] n= { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);
實例2
var firstSmallNumbers =numbers.TakeWhile((n, index) => n >= index);
此示例展示了如何通過將輸入參數括在括號中來指定多個輸入參數。該方法將返回數字數組中的所有元素,直至遇到一個值小於其位置的數字為止。不要將 lambda運算符 (=>)與大於等於運算符 (>=)混淆。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace func { //委托聲明 -- 定義一個簽名: delegate double MathAction(double num); public class Program { // 符合委托聲明的常規方法 static double Double(double input) { return input * 2; } static void Main(string[] args) { // 使用一個命名方法實例化委托類型 /* * 寫法一,需要寫出專門委托的函數,還需要自定義委托 **/ MathAction ma = Double;//注意這裡千萬不可有Double(),否則就成了一個返回類型,是報錯的,這裡是制定函數的地址,給定的是函數的地址 //調用委托 double result1 = ma(4.5); //使用系統自定義委托實例化委托類型 /* * 寫法二,需要寫出專門委托的函數,不需要自定義委托,使用系統委托 **/ Funcfunc = Double; //調用委托 double result2 = func(4.5); //系統委托使用lamdba進行傳遞參數 /* * 寫法三,不需要寫出專門委托的函數,還需要自定義委托 **/ Func result = s=> s * 2;//寫法還可以換成lamdba語句塊,適應多個參數的寫法 double result3=result(4.5); Func result4 = s => { return s * 2; }; Console.WriteLine(result1); Console.WriteLine(result3); Console.WriteLine(result2); Console.WriteLine(result4(4.5)); } } }
效果圖
同樣的輸出效果,但是編寫代碼的效果確實不同的。代碼的質量也是不同的。當然了也是要對自己的問題進行負責的。lamdba的使用簡化的代碼,但是如果自己不是對這個很熟悉,很容易造成出現問題,如從著手錯誤的源泉。匿名函數的寫法解決的這個問題。但是匿名函數卻沒有Lamdba簡便。這就是折中方法吧。看自己更喜歡哪種了。
從Func的委托中,我們可以看出,它簡化了我們自己定義委托帶來的繁瑣,同時它更好的結合了Lamdba的使用。減少了自定義函數的作用。同時也是有缺點的,就是錯誤的出現不容易發現是那裡。Action委托的使用與Func雷同,這裡就不在說了。希望自己的總結可以對大家有所幫助。