C#中委托和匿名委托的具体介绍

这篇文章主要为大家详细介绍了c#委托与匿名委托的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本来是想写一篇《委托与lambda表达式的前世今生》,但仅委托部分已经写了很多内容,于是就此分开关于Lambda表达是的内容后续再写吧。

不知道Lambda表达式是谁发明的,只记得第一次接触Lambda表达式是在使用VS2008的时候,那就先认为是微软发明的吧。

Lambda表达式从我接触开始到现在变得越来越流行,Java8中开始支持、kotlin更是对C#,F#做了广泛的抄袭(C#曾几何时不也如此对待过Java嘛)。其实这都充分说明了,Lambda表达式的重要性。要搞清楚Lambda首先需要搞清楚委托。

委托:

假设现在我们要开发一个处理两个整数的程序(假设先处理相加操作)

public class Worker    {      ///       /// 处理两个数      ///       ///       ///       ///       public int HandleTwoNumber(int a,int b)      {        return a + b;      }    }static void Main(string[] args)    {      int a = int.Parse(Console.ReadLine());      int b = int.Parse(Console.ReadLine());      Worker worker = new Worker();      int result = worker.HandleTwoNumber(a, b);      Console.WriteLine(String.Format("Result:{0}", result));      string p = Console.ReadLine();}

登录后复制

如果一段时间后,我们需要它变更为减操作:

public class Worker    {      public int HandleTwoNumber(int a,int b)      {        return a - b;      }    }

登录后复制

虽然有a+b变为a-b的变化很微小,但后续此处可能面临多次变化(由减变为除………)。有变化就应封装变化,此处我们可以将a与b的操作行为抽象出来,用什么抽象呢?委托

public class Worker    {      public delegate int TwoNumberHandleMethodDelegate(int x, int y);      public int HandleTwoNumber(int a,int b)      {        return a + b;      }    }

登录后复制

public delegate int TwoNumberHandleMethodDelegate(int x, int y);此处用delegate标注,表明这是一个委托定义。如果去掉 delegate 再来观察该定义,你会发现这就是一个没有方法体的抽象方法。所以委托的含义即:与该抽象方法签名形式相同的方法的类型。委托就是一种你定义的新数据类型,它与int、class是一样的都是数据类型。int表示整数,只要是整数都可以赋值给 int型变量;TwoNumberHandleMethodDelegate则表示,接收两个int型参数并返回int型结果的这类方法,因此满足上述要求的方法都可赋值给TwoNumberHandleMethodDelegate类型的变量。

如此一来Worker代码可修改为:

public class Worker    {      public delegate int TwoNumberHandleMethodDelegate(int x, int y);      public int HandleTwoNumber(int a, int b, TwoNumberHandleMethodDelegate handle)      {        return handle(a, b);      }    }

登录后复制

如此a、b的操作被封装起来,所有的变化均交由调用者来处理。此处的含义:HandleTwoNumber处理a、b两个整数,具体如何处理由 handle 实施。此时你可能会问,那如何来调用该方法呢?调用如下:

private static int Add(int a, int b)    {      return a + b;    }    private static int Sub(int a, int b)    {      return a - b;    }    static void Main(string[] args)    {      int a = int.Parse(Console.ReadLine());      int b = int.Parse(Console.ReadLine());      Worker.TwoNumberHandleMethodDelegate method = new Worker.TwoNumberHandleMethodDelegate(Add);      Worker worker = new Worker();      int result = worker.HandleTwoNumber(10, 10,method);       //int result = worker.HandleTwoNumber(10, 10, Sub);//简化版      Console.WriteLine(String.Format("Result:{0}", result)); }

登录后复制

根据上面的程序可知,Main代码块为worker的调用者,作为调用者而言应该最清楚自己想要让woker做的工作。因此作为被调用者的worker而言,它只需要接收调用者Main给的a参数及执行Main定制的算法method,然后按照算法执行并返回结果即可。上面代码虽然简单,但其中的意义深远,随着编程时间的增加相信你的理解将越深刻。

委托变量在进行赋值时除了标准的方式,还可以进行简化:

Worker.TwoNumberHandleMethodDelegate method = new Worker.TwoNumberHandleMethodDelegate(Add);      Worker worker = new Worker();      int result = worker.HandleTwoNumber(10, 10,method);//可简化为// int result = worker.HandleTwoNumber(10, 10,Add);

登录后复制

编译器将自动检查Add是否符合 TwoNumberHandleMethodDelegate 的定义,如果符合允许直接将方法名赋值给委托变量。

匿名委托

通过上面的示例代码,我们很容易发现 TwoNumberHandleMethodDelegate method 变量被赋值为Add(Sub),因此在调用method(…)时相当于调用Add(…..)。这样一来就可以认为

method与Add完全等效,既然等效那是否可以直接将Add的定义内容赋值给method变量呢?答案是肯定的:

static void Main(string[] args)    {      Worker.TwoNumberHandleMethodDelegate method =private static int Add(int a, int b)    {      return a + b;    };}

登录后复制

但像上面这种生拉硬套是不行的,你还需要做修改。修改内容是:因为现在的代码处于Main方法中,访问修饰符去掉,同样static也应去掉;同时编译器知道你要给method赋值,那么要赋的这个值肯定满足返回类型为int的要求,所有int在此时就多余了去掉;因为赋值之后method就等效于Add,以后调用只要通过method变量就可完成,所有Add方法名不需要去掉。如此代码变为如下形式:

static void Main(string[] args)    {      Worker.TwoNumberHandleMethodDelegate method =  (int a, int b)    {      return a + b;    };}

登录后复制

经过上面的修改内容简化了很多,但method赋值的=右端是什么东西呢?此时编译器并不能正确识别这是一个方法,因为方法的定义需要满足包含:访问修身符、返回类型、方法名、参数列表、方法体五部分内容。虽然你心里清楚这是个简化了的方法,但是编译器不懂你的心………,那没关系只要我们告诉编译器,后面的是个简化方法就可以了。

static void Main(string[] args)    {      Worker.TwoNumberHandleMethodDelegate method =  delegate(int a, int b)    {      return a + b;    };}

登录后复制

正如你所期望的那样,现在编译器已经知道了=右侧是你经过简化的方法;ok,现在可以正常赋值并使用了。

通过上面的定义我们发现,用delegate标注的简化方法没有一个像Add/Sub一样固定的名字。因此我们称这种方法叫匿名委托(我习惯称匿名方法)。

你可能还注意到该匿名委托定义完毕后就赋值给Main代码快中的局部变量method,因此当超出method的作用域后,该方法就再也没有机会调用了。这引出了匿名方法、匿名委托、匿名函数它们的最常见用法,即用来定义只需要使用一次的功能代码。

以上就是C#中委托和匿名委托的具体介绍的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2438329.html

(0)
上一篇 2025年3月3日 11:38:09
下一篇 2025年3月1日 10:52:46

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • C#如何使用ILGenerator实现动态生成函数的实例

    这篇文章主要介绍了c#使用ilgenerator动态生成函数的简单代码,需要的朋友可以参考下 游戏服务器里面总是有一大堆的配置文件需要读取, 而且这些配置文件的读取: * 要不然做成弱类型的, 就是一堆字符串或者数字, 不能看出来错误(需要…

    编程技术 2025年3月3日
    200
  • C#动态数据绘图graphic的实现方法介绍

    这篇文章主要介绍了c#实现动态数据绘图graphic的方法,结合实例形式分析了c#根据动态数据绘制2d数据表格的相关操作技巧,需要的朋友可以参考下 本文实例讲述了C#实现动态数据绘图graphic的方法。分享给大家供大家参考,具体如下: u…

    2025年3月3日
    200
  • C#中enum与string的相互转换的示例

    这篇文章主要介绍了c#中enum和string的相互转换的相关资料,需要的朋友可以参考下 C# Json转换操作 枚举类型 Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型,如果没有显式声明基础类型,则使用Int32。 注…

    编程技术 2025年3月3日
    200
  • C#如何实现loading提示控件简单的实例

    本文通过实例代码给大家介绍了c#实现简单的loading提示控件功能,代码非常简单,具有参考借鉴价值,需要的朋友参考下吧 自己画一个转圈圈的控件 using System;using System.Collections.Generic;u…

    编程技术 2025年3月3日
    200
  • C#中Observer观察者模式如何解决牛顿童鞋成绩问题的方法

    这篇文章主要介绍了c#设计模式之observer观察者模式解决牛顿童鞋成绩问题,简单讲述了观察者模式的原理并结合具体实例形式分析了使用观察者模式解决牛顿童鞋成绩问题的具体步骤相关操作技巧,并附带demo源码供读者下载参考,需要的朋友可以参考…

    2025年3月3日
    200
  • .NET Core2.0小技巧之MemoryCache问题修复解决的方法(图)

    这篇文章主要给大家介绍了关于.net core 2.0迁移小技巧之memorycache问题修复解决的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。 前言 大…

    2025年3月3日
    200
  • wapi是什么东西详细介绍

    wapi这个名词用户们可能在使用网络得时候见到过,但是对于一部分人来说肯定都不知道wapi是什么,下面就带来了详细介绍,帮助不知道小伙伴去了解。 wapi是什么东西: 答:wapi是无线局域网鉴别和保密的基础结构。 这就像红外线和蓝牙等功能…

    2025年3月3日
    200
  • 有关UML的基础介绍

    uml是什么?      unified modeling language (uml)又称统一建模语言或标准建模语言,是始于1997年一个omg标准,它是一个支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持…

    编程技术 2025年3月3日
    200
  • 比较C#中值类型和引用类型的区别

    clr支持两种类型:值类型和引用类型,看起来fcl的大多数类型是引用类型,但用的最多的还是值类型。引用类型总是从托管堆中分配,在用new操作符实例一个对象,返回对象内存地址存放在一个变量中。在使用引用类型时要了解其四个心理因素:      …

    编程技术 2025年3月3日
    200
  • 介绍C#中的堆和栈

    1、什么是堆?     堆是一块内存区域,在堆里可以分配大块的内存用于存储某类型的数据对象;   堆的特征:     1、堆里面的内存能够以任意顺序存入和移除;     2、不能显示地删除程序在堆里面保存的数据;     3、靠clr的自动…

    编程技术 2025年3月3日
    200

发表回复

登录后才能评论