以前我們為了能夠調用一個方法,必須比照這個方法定義一個相應的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()
{
Func convert = 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);
//使用系統自定義委托實例化委托類型
/*
* 寫法二,需要寫出專門委托的函數,不需要自定義委托,使用系統委托
**/
Func func = 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雷同,這裡就不在說了。希望自己的總結可以對大家有所幫助。