C#中的委托实例代码详解(图文)


当前第2页 返回上一页

1

2

3

4

5

6

7

8

9

10

11

12

public static void Say(string name,WithParaNoReturnEventHandler handler)

    {

      handler(name);

    }

   public static void SayChinese(string name)

    {

      Console.WriteLine("你好," + name);

    }

    public static void SayEnglish(string name)

    {

      Console.WriteLine("hello," + name);

    }

这样,只通过一个方法Say来进行调用。

如何调用呢?如下三种调用方式:

1

2

3

4

WithParaNoReturnEventHandler _WithParaNoReturnEventHandler = new WithParaNoReturnEventHandler(MyDelegate.SayChinese);

MyDelegate.Say("张三",_WithParaNoReturnEventHandler);

MyDelegate.Say("张三", delegate(string name) { Console.WriteLine("你好," + name); }); //匿名方法

MyDelegate.Say("张三", (name) => { Console.WriteLine("你好," + name); }); //lambda表达式

以上代码使用了几种调用方式,这些调用方式都是随着C#的升级而不断优化的。第一种是C#1.0中就存在的传统调用方式,第二种是C#2.0中的匿名方法调用方式,所谓匿名方法,就是没有名字的方法,当方法只调用一次时使用匿名方法最合适不过了。C#3中的lambda表达式。其实泛型委托同样是被支持的,而.NET 3.5则更进一步,引入了一组名为Func的泛型委托类型,它能获取多个指定类型的参数,并返回另一个指定类型的值。

lambda表达式

lambda表达式的本质就是一个方法,一个匿名方法。

如果方法体只有一行,无返回值,还可以去掉大括号和分号。

MyDelegate.Say("张三", (name) => Console.WriteLine("你好," + name));

如果方法体只有一行,有返回值,可以去掉大括号和return。

WithParaWithReturnEventHandler _WithParaWithReturnEventHandler = (name)=>name+",你好";

从.NET3.5开始,基本上不需要我们自己来申明委托了,因为系统有许多内置的委托。

Action和Func委托,分别有16个和17个重载。int表示输入参数,out代表返回值,out参数放置在最后。

Action表示无返回值的委托,Func表示有返回值的委托。因为方法从大的角度来分类,也分为有返回值的方法和无返回值的方法。

也就是说具体调用什么样的方法,完全由调用方决定了,就有了更大的灵活性和扩展性。为什么这么说,如果我有些时候要先说英语再说汉语,有些事时候要先说汉语再说英语,如果没有委托,我们会怎么样实现?请看如下代码:

1

2

3

4

5

6

7

8

9

10

public static void SayEnglishAndChinese(string name)

    {

      SayEnglish(name);

      SayChinese(name);

    }

    public static void SayChineseAndEnglish(string name)

    {

      SayChinese(name);

      SayEnglish(name);

    }

如果又突然要添加一种俄语呢?被调用方的代码又要修改,如此循环下去,是不是要抓狂了?随着不断添加新语种,代码会变得越来越复杂,越来越难以维护。这样的代码耦合性非常高,是不合理的,也就是出现了所谓的代码的坏味道,你可以通过设计模式(如观察者模式等),在不使用委托的情况下来重构代码,但是实现起来是非常麻烦的,要写很多更多的代码...

委托可以传递方法,而这些方法可以代表一系列的操作,这些操作都由调用方来决定,就很好扩展了,而且十分灵活。我们不会对已有的方法进行修改,而是只以添加方法的形式去进行扩展。

可能有人又会说,我直接在调用方那里来一个一个调用我要执行哪些方法一样可以实现这样的效果啊?

可你有没有想过,你要调用的是一系列方法,你根本无法复用这一系列的方法。使用委托就不一样了,它好比一个方法集合的容器,你可以往里面增减方法,可以复用的。而且使用委托,你可以延时方法列表的调用,还可以随时对方法列表进行增减。委托对方法进行了再一次的封装。

总结:也就是当你只能确定方法的函数签名,无法确定方法的具体执行时,为了能够更好的扩展,以类似于注入方法的形式来实现新增的功能,就能体现出委托的价值。

委托和直接调用函数的区别:用委托就可以指向任意的函数,哪怕是之前没定义的都可以,而不用受限于哪几种。

多播委托

组合的委托必须是同一个类型,其相当于创建了一个按照组合的顺序依次调用的新委托对象。委托的组合一般是给事件用的,用普通委托的时候很少用。

通过+来实现将方法添加到委托实例中,-来从委托实例中进行方法的移除。

+和-纯粹是为了简化代码而生的,实际上其调用的分别是Delegate.Combine方法和Delegate.Remove。

如果委托中存在多个带返回值的方法,那么调用委托的返回值是最后一个方法的返回值。

1

2

3

4

5

6

7

8

9

10

11

public static void MultipleShow()

    {

      //多播委托

      NoParaWithReturnEventHandler _NoParaWithReturnEventHandler = new NoParaWithReturnEventHandler(GetDateTime);

      _NoParaWithReturnEventHandler += GetDateTime;

      Console.WriteLine(_NoParaWithReturnEventHandler());

    }

    public static string GetDateTime()

    {

      return string.Format("今天是{0}号。", DateTime.Now.Day.ToString());

    }

委托总结:

  • 委托封装了包含特殊返回类型和一组参数的行为,类似包含单一方法的接口;

  • 委托类型声明中所描述的类型签名决定了哪个方法可用于创建委托实例,同时决定了调用的签名;

  • 为了创建委托实例,需要一个方法以及(对于实例方法来说)调用方法的目标;

  • 委托实例是不易变的,就像String一样;

  • 每个委托实例都包含一个调用列表――一个操作列表;

  • 事件不是委托实例――只是成对的add/remove方法(类似于属性的取值方法/赋值方法)。

常见使用场景:窗体传值、线程启动时绑定方法、lambda表达式、异步等等。

生活中的例子:现在不是大家都在抢火车票吗,使用云抢票就相当于使用委托,你可以直接自己买票,也可以托管于云抢票,自己抢票的话,在快要开枪的时候,你必须时刻刷新,下单输验证码等等,使用云抢票的话,你只要放票前,提前输入抢票信息,就再也不需要你管了,自动出票,你根本不需要知道云抢票那边是怎么帮你实现抢票的。相同时间和车次可以做成一个委托实例,有很多人都通过这个委托实例来进行抢票操作。

以上就是C#中的委托实例代码详解(图文)的详细内容!

返回前面的内容

相关阅读 >>

C#中winform制作异形窗体与控件的实现方法

C# 使用npoi生成word文档(按照模板)

具体介绍C#使用selenium+phantomjs抓取数据的案例(图文)

详细介绍使用C#实现windows form调用r进行绘图与显示的方法(图)

C#中的类型系统(值类型和引用类型)的简单介绍

具体介绍C#线程与线程池的区别

详细介绍C#中new的几种用法

详细介绍C# string格式的日期时间字符串转为datetime类型的方法

C#基础入门-简单了解注释

C#中正则表达式有什么作用?匹配字符有什么含义?

更多相关阅读请进入《C#》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...