Action、Func 委派的用法

 

在網路上看到有人解釋委派,我覺得說得不錯

委派最常見的用處,就是將我們自己的function當成參數,傳到另一個function來跑。出處

委派的範例為

using System;

namespace ConsoleApplication1
{
    class Program
    {
        public delegate string helloDelegate(string pName);

        static void Main(string[] args)
        {
            helloDelegate myHelloDelegate = ReturnMessage;

            string message = myHelloDelegate("a");

            Console.WriteLine(message);
            Console.ReadKey();
        }

        public static string ReturnMessage(string pName)
        {
            return pName;
        }
    }
}

 

一、Func 委派

1、不用明確定義委派方法,以 Func 來簡化程式碼為

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            //Func<in T, out TResult>
            Func<string, string> myHelloDelegate = ReturnMessage;

            string message = myHelloDelegate("a");

            Console.WriteLine(message);
            Console.ReadKey();
        }

        public static string ReturnMessage(string pName)
        {
            return pName;
        }
    }
}

 

特別額外舉另一例,顯示 Func<in T, out TResult> 與 Func<out TResult> 的不同

using System;

public class GenericFunc
{
    public static void Main()
    {
        //Func<out TResult>
        Func<string> sayHello = Show;
        Console.WriteLine(sayHello());
        Console.ReadKey();
    }

    private static string Show()
    {
        return "Hello";
    }
}

 

2、使用匿名方法

using System;

public class Anonymous
{
    public static void Main()
    {
        Func<string, string> convert = delegate (string s) { return s.ToUpper(); };

        string name = "Dakota";
        Console.WriteLine(convert(name));
    }
}

 

3、使用匿名方法是可以存取外部變數的

using System;

namespace ConsoleApp1
{
    class Program
    {
        delegate void Del();

        static void Main(string[] args)
        {
            int n = 0;
            Del d = delegate () { Console.WriteLine("Copy #:{0}", ++n); };
            d();
            Console.ReadKey();
        }

        //static void Show()
        //{
        //    Console.WriteLine("Copy #:{0}", ++n);
        //}
    }
}

 

4、使用Lambda運算式

using System;

public class Anonymous
{
    public static void Main()
    {
        Func<string, string> convert = s => s.ToUpper();

        string name = "Dakota";
        Console.WriteLine(convert(name));
    }
}

 

二、Action 委派

若要參考有一個參數並傳回 void (在 Visual Basic 中是宣告為 Sub 而非 Function) 的方法,

可使用泛型 Action<T> 委派代替。

using System;

public class GenericFunc
{
    public static void Main()
    {

        Action<string> aConvertMethod = UppercaseString;
        string name = "Dakota";

        aConvertMethod(name);
        Console.ReadKey();
    }

    private static void UppercaseString(string inputString)
    {
        Console.WriteLine(inputString.ToUpper());
    }
}

 

三、結論

1、Action<T>泛型的委派型別功能也是跟Func一樣,只是回傳值為void。

2、每個Func委派型別的簽章,傳入的參數會是零到四,而最後一個的型別參數是代表回傳型別。

例如:Func<string,int>,代表傳入型別為string而回型別為int。

3、Action<T>泛型委派的原型宣告為 public delegate void Action<in T>(T obj);

注意泛型參數 T 前面的修飾詞「in」,代表這是個逆變型(contravariant)參數。

 

参考資料:

Func<T, TResult> 委派

VB.NET委派