程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# Func()委托

C# Func()委托

編輯:C#入門知識

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

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

在使用 Func委托時,不必顯式定義一個封裝只有一個參數的方法的委托。以下示例簡化了此代碼,它所用的方法是實例化 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參數,因此可以給這些方法傳遞 lambda表達式,而不用顯式實例化 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雷同,這裡就不在說了。希望自己的總結可以對大家有所幫助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved