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修饰的委托也能够绑定多个方法,用法同上;
相关文章
相关标签/搜索