委托小結及Func用法


      首先,委托是一種類型,由關鍵字delegate聲明。確切的說,委托是一種可用於封裝命名或者匿名方法的引用類型。  它類似於 C++ 中的函數指針,而且是類型安全和可靠的。

      委托類型的聲明與方法簽名相似,有一個返回值和任意數目任意類型的參數。 必須使用具有兼容返回類型和輸入參數的方法或 lambda 表達式實例化委托。下面給出了委托聲明及實例化的示例代碼:

 1 // 委托聲明 -- 定義一個簽名:
 2 delegate double MathAction(double num);
 3 
 4 class DelegateTest
 5 {
 6     // 符合委托聲明的常規方法
 7     static double Double(double input)
 8     {
 9         return input * 2;
10     }
11 
12     static void Main()
13     {
14         // 使用一個命名方法實例化委托類型
15         MathAction ma = Double;
16 
17         // 調用委托實例
18         double multByTwo = ma(4.5);
19         Console.WriteLine(multByTwo);
20 
21         // 再用匿名方法來實例化委托類型
22         MathAction ma2 = delegate(double input)
23         {
24             return input * input;
25         };
26 
27         double square = ma2(5);
28         Console.WriteLine(square);
29 
30         // 最后用Lambda表達式來實例化委托類型
31         MathAction ma3 = s => s * s * s;
32         double cube = ma3(4.375);
33 
34         Console.WriteLine(cube);
35     }
36 }

以上給出了一般情況下委托的使用,那么接下來我想繼續了解Func<T, TResult>與委托的關系,還是直接從示例代碼入手,請往下看代碼:

 1 using System;
 2 
 3 delegate string ConvertMethod(string inString);
 4 
 5 public class DelegateExample
 6 {
 7    public static void Main()
 8    {
 9       // 用命名方法來實例化委托類型
10       ConvertMethod convertMeth = UppercaseString;
11       string name = "Dakota";
12       // 通過實例化后的委托實例去調用該方法
13       Console.WriteLine(convertMeth(name));
14    }
15 
16    private static string UppercaseString(string inputString)
17    {
18       return inputString.ToUpper();
19    }
20 }

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

 1 using System;
 2 
 3 public class GenericFunc
 4 {
 5    public static void Main()
 6    {
 7       // 依舊是用命名方法實例化委托類型
 8       Func<string, string> convertMethod = UppercaseString;
 9       string name = "Dakota";
10       // 依舊是通過委托實例調用該方法
11       Console.WriteLine(convertMethod(name));
12    }
13 
14    private static string UppercaseString(string inputString)
15    {
16       return inputString.ToUpper();
17    }
18 }

您也可以按照以下示例所演示的那樣在 C# 中將 Func<T, TResult> 委托與匿名方法一起使用。

 1 using System;
 2 
 3 public class Anonymous
 4 {
 5    public static void Main()
 6    {
 7       Func<string, string> convert = delegate(string s)
 8          { return s.ToUpper();}; 
 9 
10       string name = "Dakota";
11       Console.WriteLine(convert(name));   
12    }
13 }

您還可以按照以下示例所演示的那樣將 lambda 表達式分配給 Func<T, TResult> 委托。

 1 using System;
 2 
 3 public class LambdaExpression
 4 {
 5    public static void Main()
 6    {
 7       Func<string, string> convert = s => s.ToUpper();
 8 
 9       string name = "Dakota";
10       Console.WriteLine(convert(name));   
11    }
12 }

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

如果前面的解析看的不是很清楚,相信最后這個實例能夠讓你更加明白Func委托是多么有意思。

下面的示例演示如何聲明和使用 Func<T, TResult> 委托。  此示例聲明一個 Func<T, TResult> 變量,並為其分配了一個將字符串中的字符轉換為大寫的 lambda 表達式。  隨后將封裝此方法的委托傳遞給 Enumerable.Select 方法,以將字符串數組中的字符串更改為大寫。

 1 using System;
 2 using System.Collections;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 
 6 static class Func
 7 {
 8    static void Main(string[] args)
 9    {
10       // 聲明了一個Func委托類型的變量selector並用Lambda表達式進行實例化 
11       // 這個Lambda表達式將用來獲取一個字符串並將這個字符串轉化為大寫並返回
12       Func<string, string> selector = str => str.ToUpper();
13 
14       // 創建一個字符串數組
15       string[] words = { "orange", "apple", "Article", "elephant" };
16       // 依次遍歷這個字符串數組並調用委托實例selector進行處理
17       IEnumerable<String> aWords = words.Select(selector);
18 
19       // 輸出結果到控制台
20       foreach (String word in aWords)
21          Console.WriteLine(word);
22    }
23 }      
24 /*
25 This code example produces the following output:
26 
27    ORANGE
28    APPLE
29    ARTICLE
30    ELEPHANT
31 */

通過委托和Lambda表達式及Func<>特性的結合,可以看出他們帶給代碼多么大的改變,不僅讓我們的代碼更加簡潔,更讓我們的代碼執行起來更加高效靈活。個人希望通過對委托的一些整理,加深對委托的理解和運用!

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM