C# Func<>委託

來源:互聯網
上載者:User

標籤:泛型   執行個體   

以前我們為了能夠調用一個方法,必須比照這個方法定義一個相應的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<>

Func<T,TR>

T

此委託封裝的方法的參數類型。

TR

此委託封裝的方法的返回值類型。

 

在使用 Func<T,TResult>委託時,不必顯式定義一個封裝只有一個參數的方法的委託。以下樣本簡化了此代碼,它所用的方法是執行個體化 Func<T, TResult>委託,而不是顯式定義一個新委託並將命名方法分配給該委託。


使Func<>委託,我們這樣寫

using System;public classLambdaExpression{   public static void Main()   {       Func<string, string> convert = s=> s.ToUpper();//該方法將小寫字母轉為大寫      string name = "Dakota";      Console.WriteLine(convert(name));     }}

Func委託是system下的全域函數,不用我們自定,系統自訂的,供我們使用,帶有多個重載.

這裡我們除了使用Func委託外,還是用了Labdab運算式.這裡我再談談這個運算式.

Lambda運算式的基礎類型是泛型 Func委託之一。 這樣能以參數形式傳遞 lambda運算式,而不用顯式將其分配給委託。 尤其是,因為 System.Linq命名空間中許多類型方法具有Func<T, TResult>參數,因此可以給這些方法傳遞 lambda運算式,而不用顯式執行個體化 Func<T, TResult>委託。

下面一行代碼將產生一個序列,其中包含 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<double,double> func = Double; //調用委託double result2 = func(4.5); //系統委託使用lamdba進行傳遞參數/* * 寫法三,不需要寫出專門委託的函數,還需要自訂委託 **/Func<double, double> result = s=> s * 2;//寫法還可以換成lamdba語句塊,適應多個參數的寫法 double result3=result(4.5); Func<double,double> 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雷同,這裡就不在說了。希望自己的總結可以對大家有所協助。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.