(轉)C# 泛型委託 Action<>和Func<>

轉:https://www.cnblogs.com/wyongqi/p/7483748.html

如果我們希望定義一個委託類型來調用任何返回void並且接受單個參數的方法。如果這個參數可能會不同,我們就可以通過類型參數來構建。

下面我們看一個小示例:

複製代碼
public class GenericDelegate
{
    public delegate void MyGenericDelegate<T>(T arg);

    public static void Show()
    {
     // 註冊目標 MyGenericDelegate<string> stringTarget = new MyGenericDelegate<string>(StringTarget); stringTarget("i am ok"); MyGenericDelegate<int> intTarget = new MyGenericDelegate<int>(IntTarget); intTarget.Invoke(100); } static void StringTarget(string arg) => Console.WriteLine($"StringTarget--> {arg.ToUpper()}"); static void IntTarget(int arg) => Console.WriteLine($"IntTarget--> {++arg}"); }
複製代碼

 

a. 泛型Action<> 和 Func<> 委託
從以上的學習中我們已經瞭解到,使用委託在應用程序中進行回調需要遵循以下步驟:

  • 自定義一個與要指向的方法格式相匹配的委託
  • 創建自定義委託的實例,將方法名作爲構造函數的參數
  • 通過調用委託對象的Invoke()方法來間接調用該方法

 其實,這種方式通常會構建大量只用於當前任務的自定義委託。當委託名無關緊要的時候,我們可以使用框架內置的Action<> 和 Func<> 泛型委託,可指向至多傳遞16個參數的方法。

 Action<>:無返回值: 定義 public delegate void Action<...>

複製代碼
public class MyActionDelegate
{
    public static void Show()
    {
        // 使用Action<>委託來指向 DisplayMessage()
        Action<string, ConsoleColor, int> actionTarget = new Action<string, ConsoleColor, int>(DisplayMessage);
        actionTarget("actionTarget", ConsoleColor.Red, 5);
    }

    // Action<> 委託的一個目標
    private static void DisplayMessage(string msg, ConsoleColor txtColor, int printCount)
    {
        ConsoleColor previous = Console.ForegroundColor;
        Console.ForegroundColor = txtColor;

        for (int i = 0; i < printCount; i++)
        {
            Console.WriteLine(msg);
        }

        Console.ForegroundColor = previous;
    }
}
複製代碼

運行效果如下圖:

 

Func<>:有返回值 public delegate TResult Func<..., out TResult>

Func的 參數列表中,最後一個是返回類型,前面的都是參數類型

複製代碼
public class FuncDelagate
{
    public static void Show()
    {
        Func<int, int, int> funcTarget = new Func<int, int, int>(Add);
        int result = funcTarget(1, 2);
        Console.WriteLine(result);

        Func<int, int, string> funcTarget2 = new Func<int, int, string>(SumToString);
        string sumStr = funcTarget2(3, 4);
        Console.WriteLine(sumStr);
    }
        
    static int Add(int x, int y) => x + y;

    static string SumToString(int x, int y) => (x + y).ToString();
}
複製代碼

運行結果:3,7

鑑於 Action<> 和 Func<> 節省了手工創建自定義委託的步驟,but 總是應該使用他們嗎?

答案:“視情況而定”。

很多情況下 Action<> 和 Func<> 都是首選,但如果你覺得一個具有自定義名稱的委託更有助於捕獲問題範疇,那麼構建自定義委託不過就是一行代碼的事兒。

注:Linq中就大量的用到了 Action<> 和 Func<>。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章