Unity3D學習資源:委託和lambda表達式一

 

一.在C#中咱們能夠使用delegate關鍵字來聲明一個委託,聲明的格式以下:

delegate <函數返回類型> <委託名> (<函數參數>)編程

下面咱們來看一下代碼是如何來寫的:閉包

[C] 純文本查看 複製代碼函數

using System;
using System.Collections.Generic;

namespace demo
{
        //聲明一個委託,兩個int類型的參數,一個int類型的返回值
        delegate int MyDelegate(int x,int y);
        class Test
        {
                //求兩個數的和,兩個int類型的參數,int類型的返回值;
                public int Sum(int a, int b)
                {
                        return a + b;
                }
                //兩個數的差,兩個int類型的參數,int類型的返回值
                static public int Min(int a, int b)
                {
                        return a - b;
                }
        }

        class MainClass
        {
                

                public static void Main(string[] args)
                {
                        //建立Test類的一個對象
                        Test test = new Test();

                        //聲明一個MyDelegate類型的變量,因爲該類型的委託在聲明時有兩個int類型的參數和int類型的返回值
                        //其格式與Test類中Sum和Min兩個方法的格式同樣,故能夠直接把這兩個方法賦值給該委託類型的變量mydel
                        //這時能夠說委託綁定了方法,它不只能夠綁定類方法,也能夠綁定實例方法
                        MyDelegate mydel = Test.Min;//綁定了類方法
                        MyDelegate mydel1 = test.Sum;//綁定了實例方法
                        //委託變量的使用與方法的使用是同樣的,也要帶參數,也有返回值
                        Console.WriteLine(mydel1(2, 3));
                }
        }
}

在名字空間內部,類的外部建立一個委託類型MyDelegate,其聲明的格式爲:返回值int類型,參數有兩個,都是int類型.你們能夠看到該委託的格式與Test類裏面的Sum和Min方法在格式外形上來看是一致的.在Main方法裏面,咱們就能夠把Sum方法直接賦值給MyDelegate的一個變量,此時咱們能夠說把一個方法綁定給了一個委託變量,從上面的代碼中能夠看到,委託不只能夠綁定類方法,也能夠綁定實例方法.spa

從上面的代碼咱們能夠獲得以下的結論:code

1.在聲明委託時有必定的格式,咱們就能夠把與該委託格式同樣的方法名直接賦值給該委託的一個變量;對象

2.從某種意義上來說,委託至關於一個方法模版,把與該模版相同的方法賦值給委託變量後,使用委託變量時,本質上來說就是使用其所綁定的方法;ci

3.委託變量的使用與方法的使用是同樣的,若是有參數,委託變量後面必定要帶小括號,裏面要加參數,而且個數和類型要一致,若是沒有參數,也要加小括號;string

(其它三種格式的委託你們能夠本身練習試着作一下)it

委託不只能夠綁定一個方法,還能夠綁定多個方法,以下代碼:io

[C] 純文本查看 複製代碼

using System;
using System.Collections.Generic;

namespace demo
{
        //聲明一個委託,一個string類型的參數,無返回值
        delegate void GreetDelegate(string str);
        class Test
        {
                //一個string類型的參數,無返回值
                public void ChineseGreet(string name)
                {
                        Console.WriteLine("早上好!!" + name);
                }
                //一個string類型的參數,無返回值
                public void EnglishGreet(string name)
                {
                        Console.WriteLine("Good morning!!" + name);
                }
        }

        class MainClass
        {
                

                public static void Main(string[] args)
                {
                        //建立Test類的一個對象
                        Test test = new Test();

                        //綁定了第一個方法
                        GreetDelegate greet = test.ChineseGreet;
                        //綁定第二個方法,用+=運算符,一般稱爲委託合併
                        greet += test.EnglishGreet;
                        greet("lisi");

                }
        }
}

咱們在給委託變量綁定第一個方法時,直接用賦值運算符,這樣才能夠使委託變量進行實例化,不然是不能用的,綁定第二個方法時,用+=運算符,這樣委託變量就同時綁定了兩個方法,一般也稱爲委託合併,在Main方法裏面使用委託時,會調用所綁定的兩個方法,把結果打印出來,所綁定的方法是有前後順序的,先綁定的方法會先執行.使用委託時只須要記住一點:即委託所綁定的方法從格式上兩者要一致.

以上的兩個例子,委託在綁定方法時,都會先把方法建立好,下面講另外兩種委託,匿名委託和lambda表達,這樣就不用再建立方法了.下面的代碼是把上面的例子用匿名委託改寫的,代碼以下:

[C] 純文本查看 複製代碼

public static void Main(string[] args)
                {
                        Greet greet = delegate(string str)
                        {
                                        Console.WriteLine("早上好!!" + str);
                        };
                        greet += delegate(string str)
                        {
                                        Console.WriteLine("Good Morning!!" + str);
                        };
                        greet("小李");
                }

其結果與上面的同樣,使用匿名委託時其格式爲:delegate(){};小括號裏面爲參數,大括號裏面是方法體,具體是否有返回值,以及參數個數和參數類型要與其所賦值的委託格式一致,若是有返回值,則只須要在大括號裏面return一個返回值便可;如把上面的第一個例子用匿名委託更改以下:

[C] 純文本查看 複製代碼

MyDelegate mydele = delegate(int a, int b)
                        {
                                return a + b;
                        };

因爲MyDelegate的格式爲:返回值爲int類型,參數2個,都是int類型,因此匿名委託的參數也要有兩個而且都是int類型,在{}裏面要有一個返回值.下面再看另一種匿名委託,lambda表達式,其在C++中稱爲閉包,其格式以下: (()=>{}),具體的使用方法請看如下代碼:

[C] 純文本查看 複製代碼

MyDelegate mydele = ((int a, int b) =>
                        {
                                return a + b;
                        });
                        Console.WriteLine(mydele(2, 3));

結果和上面的例子是同樣的.你們只須要記住其格式便可,(()=>{}),小括號裏時面是參數,大括號裏面是方法體.只要你們看得多了,就會習慣這種編程方法了.

下面一種委託是Func委託,格式爲Func<形參1類型,形參2類型...返回值類型> 委託變量名;<>裏面的最後一個爲返回值類型,前面的都是參數類型,該委託必定要有返回值.具體的代碼以下:

[C] 純文本查看 複製代碼

Func<int,int,int> s = test.Sum;
                        Console.WriteLine(s(3, 4));

最後一種委託是Action委託,格式爲Action<形參類型> 委託變量名;<>裏面是形參類型,參數能夠有多個,此委託沒有返回值,具體的用法以下代碼:

[C] 純文本查看 複製代碼

Action<string> action = test.ChineseGreet;
                        action("lisi");

二.上面的例子咱們看到,定義的委託都是在類外面,名字空間下面的,全部的類均可以用該委託,這與咱們講的面向對象的三大特性封裝是相違背的,此時咱們就把委託放到類裏面,而後在類裏面建立一個public修飾的委託變量,而後在類的外面就能夠拿到該委託變量,進而使用它.具體的代碼以下:

[C] 純文本查看 複製代碼

class Test
        {
                public delegate void PrintDelegate();

                public PrintDelegate printdel;
public void Print()
                {
                        Console.WriteLine("藍鷗科技");
                }
}

//下面是Main方法
public static void Main(string[] args)
                {

                        //建立Test類的一個對象
                        Test test = new Test();
                        test.printdel = test.Print;
                        test.printdel();
}

具體的其它用法同上面;

三.event關鍵字若是類裏面的一個委託變量用public event來修飾,在類的外面能夠直接拿到該委託變量,而且在綁定方法的時候,只能用+=運算符,即便綁定第一個方法,也要用+=運算符,可是有一點,綁定方法之後,不可以直接使用,必須把該委託變量放到類裏面的方法裏面.具體的代碼以下:

[C] 純文本查看 複製代碼

class Test
        {
                public delegate void PrintDelegate();
                public  PrintDelegate printdel;
                //用event修飾委託變量
                public event PrintDelegate eventdelegate;
//調用該方法,才能夠執行方法裏面的委託
 public void EventPrint(){
                        eventdelegate();
                }
                public void Print()
                {
                        Console.WriteLine("藍鷗科技");
                }
}
        public static void Main(string[] args)
                {

                        //建立Test類的一個對象
                        Test test = new Test();
test.eventdelegate += test.Print;
                        test.EventPrint();

}
event修飾的委託也能夠綁定多個方法,用法同上;
相關文章
相關標籤/搜索