委派與匿名方法演化至Lambda運算式

 

一、委派的使用步驟

1 、利用 delegate 關鍵字把方法簽章塑造成一種型別

public delegate string helloDelegate(string pName);

 

2、建立委派實體物件

helloDelegate myHelloDelegate = new helloDelegate(pg.ReturnMessage);

也可以寫成

helloDelegate myHelloDelegate = ReturnMessage;

也可以寫成匿名委派

helloDelegate myHelloDelegate = delegate (string pName) { return pName; };

 

如果匿名委派方法沒有輸入參數,則可寫成下列型式

helloDelegate myHelloDelegate = delegate () { return ""; };

helloDelegate myHelloDelegate = delegate { return ""; };

 

3、使用委派實體物件

string message = myHelloDelegate("a");

 

4 、整個範例如下

using System;

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

        static void Main(string[] args)
        {
            Program pg = new Program();

            helloDelegate myHelloDelegate = new helloDelegate(pg.ReturnMessage);

            string message = myHelloDelegate("a");

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

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

 

5、另一種寫法

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 string ReturnMessage(string pName)
        {
            return pName;
        }
    }
}

注意紅色字會出錯,原因為

「Error 1 An object reference is required for the non-static field, method, or property 'ConsoleApplication1.Program.ReturnMessage(string)'

所以ReturnMessage前必須要再加上static以宣告為靜態方法

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

 

6、匿名委派

using System;

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

        static void Main(string[] args)
        {
            helloDelegate myHelloDelegate = delegate (string pName) { return pName; };

            string message = myHelloDelegate("a");

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

 

小結:

a、委派是事件的基礎。

b、委派是一種回呼機制。

 

二、Lambda 運算式

1、Lambda 運算式是由稱之為「goes to」Lambda 運算子「=>」所組成,

用以取代匿名方法所引用的 delegate,

語法格式為 (input parameters) => (expression)

using System;

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

        static void Main(string[] args)
        {
            helloDelegate myHelloDelegate = (string pName) => { return pName; };

            string message = myHelloDelegate("a");

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

 

2、也可不需要大括號與 return

using System;

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

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

            string message = myHelloDelegate("a");

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

 

3、可不指定輸入型別

using System;

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

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

            string message = myHelloDelegate("a");

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

 

四、其他類似範例

例:取得每個人的名稱

List<T> 所提供的 ConvertAll 方法

var names = people.ConvertAll(p => p.name);

 

Enumerable 的 select 擴充方法

var names = Enumerable.select(people, p => p.name);

 

使用比較直覺的寫法

var names = people.Select(p => p.name);

 

使用查詢運算式

var names = from p in people select p.name;

 

參考資料:

Func 委派的用法

C# 筆記:Expression Trees

Expression-bodied members (C# programming guide)