C#委托

C#委托


++委托的定义数据库

++++delegate(委托)是表示将方法做为参数传递给其余方法。 委托相似于函数指针,但与函数指针不一样的是,委托是面向对象的,类型安全的和保险的。 委托既能引用静态方法,也能引用实例方法。编程


++委托的引入小程序

++++在引入委托以前,咱们先来看一段代码:设计模式

 

class HelloWorld{安全

    public void GreetPeople(string name){网络

        EnglishGreeting(name);函数式编程

}函数

public void EnglishGreeting(string name){学习

    Console.WriteLine(Morning, + name);测试

}

}

 

++++假设之后这段代码须要全球化,加入中国人问候的方法。

--首先须要添加中国人问候的方法修改代码以下:

    public void ChineseGreeting(string name){

        Console.WriteLine(早上好, + name);

}

 

++++而后添加枚举来区分语言,修改代码以下:

enum Language{

    English,

    Chinese

}

 

++++为调用ChineseGreeting()这个方法咱们一样须要修改GreetingPeople()这个方法:

public void GreetPeople(string name,Language language){

    if(language == Language.Chinese){

        ChineseGreeting(name);

}else if(language == Language.English){

    EnglishGreeting(name);

}

}

 

++++最终代码以下:

class HelloWorld{

public void GreetPeople(string name,Language language){

    //这里的Language为上文提到的枚举

    if(language == Language.Chinese){

    ChineseGreeting(name);

}else if(language ==Language.English){

    EnglishGreeting(name);

}

}

public void EnglishGreeting(string name){

    Console.WriteLine(Morning, + name);

}

public void ChineseGreeting(string name){

    Console.WriteLine(早上好, + name);

}

}

 

++++这个小程序真的作好了吗?

--上面的方案你们很容易想到。 利用枚举去扩展语言。 可是这个解决方案 扩展性不好。 假如往后咱们须要加入 日语,韩语,拉丁语等。 那咱们不得不反复修改 枚举添加新的语言 和GreetingPeople()内部利用if ... else或者switch分支去根据传入的参数,判断调用某个语言进行问好。


++声明并定义委托

class HelloWorld{

    //声明委托

    public delegate void GreetingDelegate(string name);

    ......

}

-- void表示委托表明的方法的返回值类型。

-- string name表示委托表明的方法的参数类型。

++++有了委托以后咱们能够修改GreetPeople(string name, **** method),代码以下:

public void GreetingPeople(string name,GreetingDelegate method){

    //委托的调用方法同方法调用同样

    method(name);

}

--这里的GreetingDelegate就是method的类型,或者叫类。 须要注意的是委托的声明方式和类却彻底不一样。 实际上,委托在编译的时候确实会编译成类由于Delegate是一个类,因此在任何能够声明类的地方均可以声明委托


++利用委托实现最终代码效果

  class HelloWorld{

      public delegate void GreetingDelegate(string name);

      public static void EnglishGreeting(string name){

          Console.WriteLine(hello, + name);

}

public static void ChineseGreeting(string name){

    Console.WriteLine(你好, + name);

}

public void GreetingPeole(string name,GreetingDelegate method){

    method(name);

}

}

--测试运行代码

  class Program{

      static void Main(string[] args){

          HelloWorld hw = new HelloWorld();

          hw.GreetingPeople(中国人, HelloWorld.ChineseGreeting);

          Console.ReadKey();

}

}


++总结

++++委托是一个类,它定义了方法的类型,使得能够将方法看成另外一个方法的参数来进行传递,这种将方法动态地赋给参数的作法,能够避免在程序中大量使用 If-Else(Switch)语句,同时使得程序具备更好的可扩展性。


++将方法绑定到委托

 

++++既然委托同string都是类型,那咱们也能够利用委托声明相似name这样的委托变量。 修改代码以下:

class Program{

    static void Main(string[] args){

        HelloWorld hw = new HelloWorld();

        HelloWorld.GreetingDelegate delegate1, delegate2;

        delegate1 = HelloWorld.EnglishGreeting;

        delegate2 = HelloWorld.ChineseGreeting;

        hw.GreetingPeople(中国人, delegate1);

        hw.GreetingPeople(yanlz, delegate2);

        Console.ReadKey();

}

}

 

++++如你所料,这样是没有问题的。 委托不一样于string的一个特征: 能够将多个方法赋给同一个委托,或者叫将多个方法绑定到同一个委托,当调用这个委托的时候,将依次调用其所绑定的方法。 以下:

HelloWorld.GreetingDelegate delegate1;

delegate1 = HelloWorld.EnglishGreeting;

delegate1 += HelloWorld.ChineseGreeting;

hw.GreetingPeople(yanlz, delegate1);

 

++++实际上咱们能够绕过调用GreetingPeople(),经过委托来直接调用EnglishGreetingChineseGreeting

HelloWorld.GreetingDelegate delegate1;

delegate1 = HelloWorld.EnglishGreeting;

delegate1(yanlz);

 

++++委托绑定方法时须要注意(多播委托), 注意这里,第一次用的“=”,是赋值的语法; 第二次,用的是“+=”,是绑定的语法。 若是第一次就使用“+=”,将出现“使用了未赋值的局部变量”的编译错误。

++++既然委托属于类,咱们也能够利用这一特性直接new出委托实例。

HelloWorld.GreetingDelegate delegate1 = new HelloWorl.GreetingDelegate(HelloWorld.ChineseGreeting);

delegate1 += HelloWorld.EnglishGreeting;

delegate1(yanlz);

 

++++既然给委托能够绑定一个方法,那么也应该有办法取消对方法的绑定。 很容易想到,利用-=,代码以下:

HelloWorld.GreetingDelegate delegate1 = new HelloWorld.GreetingDelegate(HelloWorld.ChineseGreeting);

delegate1 += HelloWorld.EnglishGreeting;

delegate1(yanlz);

delegate1 -= HelloWorld.ChineseGreeting;

delegate1(yanlz);


++匿名函数

++++咱们利用委托实现一个按钮的点击事件

首先咱们先声明一个类,代码以下:

public delegate void Click();

class Button{

    public static void ClickFinished(){

        Console.WriteLine(按钮被点击了!~);

}

}

 

Click dele1;

dele1 = Button.ClickFinished;

dele1();

 

运行程序,输出按钮被点击了!~  这属于咱们常规的委托,绑定方法。

    

++++利用匿名函数实现,修改代码以下:

Click click = delegate(){

    Console.WriteLine(按钮被点击了2222);

}

click();

运行程序,输出  按钮被点击了2222


++总结

++++之前咱们都是先声明委托,在赋值对应的方法或者直接new关联一个方法。 实际上匿名方法的出现就是在初始化时内敛声明的方法,使得委托的语法更简洁


++C#中内置了三种委托方式

++++1Func委托

++++2Action委托

++++3Predicate委托


++Func委托

++++Func委托的5种类型

  --1delegate TResult Func<TResult>

  --2delegate TResult Func<T1, TResult>(T1 arg1)

  --3delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2)

  --4delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3)

  --5delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4)

++++Func委托类型说明:

  --1)只能委托无参可是有返回值的函数,TResult就是其返回类型。

  --2)只能委托具备一个传入参数,有返回值的函数,T1为一个传入参数,TResult为返回类型。

  --3)只能委托具备二个传入参数,有返回值的函数,T1T2为两个传入参数,TResult为返回类型。

  --4)和(5),以此类推。

++++Func委托总结

使用Func委托函数必须带有返回值,即TResult

Func<string> func = delegate(){

    return我是func<TResult>委托出来的结果;

};

string result = func();

Console.WriteLine(result);

--注: 这里为了演示func委托,直接用的匿名方法,咱们一样能够为func委托绑定方法,这里不作演示。

 

++++Func委托总结(第二种func类型演示)

Func<string, string> func2= delegate(strings){

    returns.ToLower();

}

string result2 = func2(HELLO);

Console.WriteLine(result2)

--注: 这里为了演示func委托,直接用的匿名方法,咱们一样能够为func委托绑定方法,这里不作演示。

++++Func委托总结(第三种func类型演示)

Func<stirng, string, string> func3= delegate(string value1,string value2){

    return value1 +  + value2;

}

Console.WriteLine(func3(我是,Func<T1, T2, TResult>委托出来的结果));

--注: 这里为了演示func委托,直接用的匿名方法,咱们一样能够为func委托绑定方法,这里不作演示。


++Action委托

++++Action委托的5种类型

-- 1delegate void Action();  无参,无返回值

-- 2delegate void Action<T>(T1 arg1);

-- 3delegate void Action<T1, T2>(T1 arg1, T2 arg2);

-- 4delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);

-- 5delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);

++++Action委托类型说明:

--1)没有传入参数,也没有返回值,那么它适合代理那些无参,无返回值的函数。

--2)有一个传入参数,无返回值,适合代理有参,无返回值的函数。

--3)有两个传入参数,无返回值,适合代理有参*2,无返回值的函数

--4)和(5),以此类推。


++委托总结

++++至于Predicate委托用的太少,这里不作叙述。

++++注意:Func委托和Action委托惟一的区别就是在于代理的方法(函数)有没有返回值。

--有返回值选择Func委托。

--没有返回值选择Action委托。

++++系统内置的两种委托绝大多数状况下能够适配任何状况,无需咱们在写大量的代码去定义委托。可是不表明内置委托匹配任何状况。 根据特殊状况还需咱们手动定义委托,切记。


++Lambda表达式

++++Lambda”表达式是一个匿名函数,是一种高效的相似于函数式编程的表达式,Lambda简化了开发中须要编写的代码量。它能够包含表达式和语句,而且能够用建立委托或表达式目录树类型,支持带有可绑定到委托或表达式树的输入参数的内敛表达式。全部Lambda表达式都使用Lambda运算符=>,该运算符读做“goes to”。

++++Lambda运算符的左边是输入参数(若是有),右边是表达式或语句块。

++++Lambda表达式是由.NET2.0演化而来的,也是LINQ的基础,熟练地掌握Lambda表达式可以快速地上手LINQ应用开发。

++++初识Lambda表达式

首先咱们先声明一个类包含三个委托,代码以下:

class Lambda{

    public delegate void delegate1(string name); //带参数的委托

    public delegate void delegate2();  //不带参数的委托

    public delegate int delegate3(int x,int y); //有返回值有参数的委托

}

++++Lambda表达式的使用

delegate1 d1 = (x) => {

    Console.WriteLine(这是一个用Lambda表达式委托,参数为 + x);

}

d1(严立钻); //调用

 

delegate3 d3 = (x, y) => {

    Console.WriteLine(这是一个用Lambda表达式委托带两个参数,和返回值);

    returnx + y;

};

Console.WriteLine(d3(1, 2));

++++Lambda表达式案例演示

下面咱们利用lambda表达式,实现一个小功能。假设存在某个课程集合,咱们须要知道这个集中中包含哪几个课程,哪几个是vip课程,利用lambda表达式实现。




#立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/

++立钻哥哥推荐的拓展学习连接(Link_Url

++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/

++++C#事件http://www.javashuo.com/article/p-zmwruvql-gm.html

++++C#委托http://www.javashuo.com/article/p-uozpymaf-gh.html

++++C#集合http://www.javashuo.com/article/p-sfqfdqsf-ex.html

++++C#泛型http://www.javashuo.com/article/p-xrttqngo-ee.html

++++C#接口http://www.javashuo.com/article/p-vhlfplgv-dm.html

++++C#静态类https://blog.csdn.net/vrunsoftyanlz/article/details/78630979

++++C#中System.String类http://www.javashuo.com/article/p-olslkfao-cq.html

++++C#数据类型http://www.javashuo.com/article/p-hmabbtmc-ba.html

++++Unity3D默认的快捷键http://www.javashuo.com/article/p-wuwcrclr-s.html

++++游戏相关缩写http://www.javashuo.com/article/p-mwacxwca-gm.html

++++Unity引擎基础http://www.javashuo.com/article/p-beommoeb-ka.html

++++Unity面向组件开发http://www.javashuo.com/article/p-eigmuvut-dt.html

++++Unity物理系统http://www.javashuo.com/article/p-nqvvciwv-kd.html

++++Unity2D平台开发http://www.javashuo.com/article/p-ycaagdtj-hs.html

++++UGUI基础http://www.javashuo.com/article/p-rukxwckw-mc.html

++++UGUI进阶http://www.javashuo.com/article/p-wcatruhq-gt.html

++++UGUI综合http://www.javashuo.com/article/p-dkccmqii-gg.html

++++Unity动画系统基础http://www.javashuo.com/article/p-mbrdouxy-dq.html

++++Unity动画系统进阶http://www.javashuo.com/article/p-aqaqpbkh-bp.html

++++Navigation导航系统http://www.javashuo.com/article/p-dswwllas-t.html

++++Unity特效渲染http://www.javashuo.com/article/p-ckojjyfj-bp.html

++++Unity数据存储http://www.javashuo.com/article/p-bvlzynso-m.html

++++Unity中Sqlite数据库http://www.javashuo.com/article/p-ejutsbxl-ca.html

++++WWW类和协程http://www.javashuo.com/article/p-dbwmhsav-cy.html

++++Unity网络http://www.javashuo.com/article/p-sqrlntgh-dw.html

++++设计模式简单整理http://www.javashuo.com/article/p-rngqugib-hg.html

++++U3D小项目参考https://blog.csdn.net/vrunsoftyanlz/article/details/80141811

++++UML类图http://www.javashuo.com/article/p-sxberuew-bm.html

++++Unity知识点0001http://www.javashuo.com/article/p-ryvdxxjr-ep.html

++++U3D_Shader编程(第一篇:快速入门篇)http://www.javashuo.com/article/p-kyppgrac-gz.html

++++U3D_Shader编程(第二篇:基础夯实篇)http://www.javashuo.com/article/p-qkyowtli-hv.html

++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/


--_--VRunSoft:lovezuanzuan--_--