委托

委托是什么?

委托是一种引用类型(其实就是一个类,继承MulticastDelegate特殊的类。),表示对具有特定参数列表和返回类型的方法的引用。

每个委托提供Invoke方法, BeginInvoke和EndInvoke异步方法

为什么需要委托?

  • 委托可以将方法(即逻辑)作为参数;

    • 逻辑解耦,保持稳定。
    • 代码复用,保证项目规范。

如何使用委托?

如何声明、实例化和使用委托

声明委托

  1. delegate void Del(string str);
  2. static void Notify(string name)
  3. {
  4. Console.WriteLine($"Notification received for: {name}");
  5. }

实例化委托

  1. Del del1 = new Del(Notify);
  2. //C# 2.0
  3. Del del2 = Notify;

调用委托

  1. del1.Invoke("小明");
  2. del2("小明");

其他使用委托

  1. //C# 2.0使用匿名方法来声明和实例化委托
  2. Del del3 = delegate(string name)
  3. { Console.WriteLine($"Notification received for: {name}"); };
  4. //C# 3.0使用lambda表达式声明和实例化委托
  5. Del del4 = name => { Console.WriteLine($"Notification received for: {name}"); };

简化开发过程,.NET 包含一组委托类型:

  • Action<> 具有参数且不返回值。
  • Func<> 具有参数且返回由参数指定的类型的值。
  • Predicate<> 用于确定参数是否满足委托条件的情况。

实际案例

代码:

  1. class Program
  2. {
  3. /// <summary>
  4. /// 声明委托
  5. /// </summary>
  6. /// <param name="fullName"></param>
  7. private delegate void KillDelegate(string fullName);
  8. static void Main(string[] args)
  9. {
  10. //实例化委托
  11. var killWithKnifeDelegate = new KillDelegate(KillWithKnife);
  12. Kill("郭靖", killWithKnifeDelegate);
  13. var killWithSwordDelegate = new KillDelegate(KillWithSword);
  14. Kill("黄蓉", killWithSwordDelegate);
  15. var killWithAxeDelegate = new KillDelegate(KillWithAxe);
  16. Kill("欧阳克", killWithAxeDelegate);
  17. Console.ReadKey();
  18. }
  19. static void Kill(string fullName, KillDelegate killDelegate)
  20. {
  21. Console.WriteLine($"{fullName}遇到怪物");
  22. //调用委托
  23. killDelegate.Invoke(fullName);
  24. Console.WriteLine($"{fullName}增长10经验");
  25. }
  26. static void KillWithKnife(string fullName)
  27. {
  28. Console.WriteLine($"{fullName}用刀杀怪物");
  29. }
  30. static void KillWithSword(string fullName)
  31. {
  32. Console.WriteLine($"{fullName}用剑杀怪物");
  33. }
  34. static void KillWithAxe(string fullName)
  35. {
  36. Console.WriteLine($"{fullName}用斧杀怪物");
  37. }
  38. }

Lambda表达式

Lambda是什么?

Lambda就是使用委托的更方便的语法。

  1. //C# 2.0使用匿名方法来声明和实例化委托
  2. Del del3 = delegate(string name)
  3. { Console.WriteLine($"Notification received for: {name}"); };
  4. //C# 3.0使用lambda表达式声明和实例化委托
  5. Del del4 = name => { Console.WriteLine($"Notification received for: {name}"); };

为什么需要Lambda?

简化开发过程,并不会影响运行性能。

如何使用Lambda?

表达式lambda基本形式:

  1. //仅当 lambda 只有一个输入参数时,括号才是可选的;否则括号是必需的
  2. (input-parameters) => expression

使用空括号指定零个输入参数:

  1. Action line = () => Console.WriteLine();

括号内的两个或更多输入参数使用逗号加以分隔:

  1. Func<int, int, bool> testForEquality = (x, y) => x == y;

语句lambda

  1. (input-parameters) => { <sequence-of-statements> }

语句 lambda 的主体可以包含任意数量的语句;

  1. Action<string> greet = name =>
  2. {
  3. string greeting = $"Hello {name}!";
  4. Console.WriteLine(greeting);
  5. };
  6. greet("World");
  7. // Output:
  8. // Hello World!

使用匿名委托和lambda代码:

  1. public static void Main(string[] args)
  2. {
  3. List<int> list = new List<int>();
  4. for (int i = 1; i <= 100; i++)
  5. {
  6. list.Add(i);
  7. }
  8. //使用匿名委托
  9. List<int> result = list.FindAll(
  10. delegate (int no)
  11. {
  12. return (no % 2 == 0);
  13. }
  14. );
  15. foreach (var item in result)
  16. {
  17. Console.WriteLine(item);
  18. }
  19. //使用Lambda
  20. List<int> result = list.FindAll(i => i % 2 == 0);
  21. foreach (var item in result)
  22. {
  23. Console.WriteLine(item);
  24. }
  25. }

事件

事件是什么?

事件是一种特殊的委托类型,主要用于消息或通知的传递。事件只能从事件的发布类型中调用,并且通常基于EventHandler委托,该委托具有代表事件发送者的对象和System.EventArgs派生的类,其中包含有关事件的数据。

何时使用委托和事件?

  • 侦听事件是可选的:如果你的代码必须调用由订阅服务器提供的代码,则应使用基于委托的设计。如果你的代码在不调用任何订阅服务器的情况下可完成其所有工作,则应使用基于事件的设计。
  • 返回值需要委托:用于事件的委托均具有无效的返回类型,事件处理程序通过修改事件参数对象的属性将信息传回到事件源。
  • 事件具有专用调用:包含事件的类以外的类只能添加和删除事件侦听器;只有包含事件的类才能调用事件。

如何使用事件?

发布事件

定义事件数据

  1. public class CustomEventArgs : EventArgs
  2. {
  3. public CustomEventArgs(string message)
  4. {
  5. Message = message;
  6. }
  7. public string Message { get; set; }
  8. }

声明发布类中的事件

  1. public delegate void CustomEventHandler(object sender, CustomEventArgs args);
  2. public event CustomEventHandler RaiseCustomEvent;
  3. //使用泛型版本
  4. public event EventHandler<CustomEventArgs> RaiseCustomEvent;

订阅事件

定义一个事件处理程序方法

  1. void HandleCustomEvent(object sender, CustomEventArgs a)
  2. {
  3. // Do something useful here.
  4. }

使用(+=) 添加订阅事件

  1. publisher.RaiseCustomEvent += HandleCustomEvent;

使用(-=) 取消订阅事件

  1. publisher.RaiseCustomEvent -= HandleCustomEvent;

示例

  1. using System;
  2. namespace DotNetEvents
  3. {
  4. // 定义事件信息的类
  5. public class CustomEventArgs : EventArgs
  6. {
  7. public CustomEventArgs(string message)
  8. {
  9. Message = message;
  10. }
  11. public string Message { get; set; }
  12. }
  13. // 发布事件的类
  14. class Publisher
  15. {
  16. // 使用EventHandler <T>声明事件
  17. public event EventHandler<CustomEventArgs> RaiseCustomEvent;
  18. public void DoSomething()
  19. {
  20. RaiseCustomEvent(new CustomEventArgs("Event triggered"));
  21. }
  22. }
  23. //订阅事件的类
  24. class Subscriber
  25. {
  26. private readonly string _id;
  27. public Subscriber(string id, Publisher pub)
  28. {
  29. _id = id;
  30. // 添加订阅事件
  31. pub.RaiseCustomEvent += HandleCustomEvent;
  32. }
  33. // 定义一个事件处理程序方法。
  34. void HandleCustomEvent(object sender, CustomEventArgs e)
  35. {
  36. Console.WriteLine($"{_id} received this message: {e.Message}");
  37. }
  38. }
  39. class Program
  40. {
  41. static void Main()
  42. {
  43. var pub = new Publisher();
  44. var sub1 = new Subscriber("sub1", pub);
  45. var sub2 = new Subscriber("sub2", pub);
  46. // 调用引发事件的方法
  47. pub.DoSomething();
  48. Console.ReadKey();
  49. }
  50. }
  51. }

参考

.NET委托,事件和Lambda表达式的更多相关文章

  1. 委托,事件,lambda表达式

    开篇说明三个点: 委托是一种类型 事件是委托的实例 lambda表达式是一个方法(匿名方法) [未完待续]

  2. C++实现委托机制(三)——lambda表达式封装

    C++.引言:              其实原本没打算写这一章的,不过最后想了想,嗯还是把lambda表达式也一并封装进去,让这个委托也适应lambda表达式的注册.不过在之前还是需要先了解lamb ...

  3. 委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件【转】

    1. 委托 From: http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html 类是对象的抽象,而委托则可以看成是函数的抽象.一个委 ...

  4. (28)C#委托,匿名函数,lambda表达式,事件

    一.委托 委托是一种用于封装命名和匿名方法的引用类型. 把方法当参数,传给另一个方法(这么说好理解,但实际上方法不能当参数,传入的是委托类型),委托是一种引用类型,委托里包含很多方法的引用 创建的方法 ...

  5. C#多线程+委托+匿名方法+Lambda表达式

    线程 下面是百度写的: 定义英文:Thread每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.进程也可能是整个程序或者是部分程序的动态执行.线程是一组指令的集合,或者是程序的特殊段,它 ...

  6. 委托初级篇——lambda表达式的推导

    public delegate void ConsoleWriteStr(string name,DateTime now); public delegate int DelegateAdd(int ...

  7. 委托、回调 Lambda表达式书写方式

  8. C#从委托、lambda表达式到linq总结

    前言 本文总结学习C#必须知道的基础知识,委托.监视者模式.常用lambda表达式.linq查询,自定义扩展方法,他们之间有什么关系呢?匿名委托是如何演变成lambda表达式,lambda再如何导出l ...

  9. 委托的lambda表达式

    委托可以用 Lambda 表达式的方法来表示,很多C#的代码都会大量使用 Lambda 表达式,正确理解它的用法还是很重要的. 基础规则: Lambda 运算符 “=>” 左边表示委托实例所需要 ...

随机推荐

  1. JS学习第八天

    DOM访问列表框.下拉菜单的常用属性: form返回列表框.下拉菜单所在的表单对象; length返回列表框.下拉菜单的选项个数; options返回列表框.下拉菜单里所有选项组成的数组; defau ...

  2. C#算法设计查找篇之02-二分查找

    二分查找(Binary Search) 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/699 访问. 二分查找也称折半查 ...

  3. JavaScript 回调函数的简单示例

    回调函数 回调函数也被称为高阶函数 所谓高阶函数,就是说值 函数作为参数被传递或者返回值输出 操作函数的函数称为 高阶函数 把一段可执行的代码(一个函数)作为参数传递给其他的代码(另一个函数),并在需 ...

  4. 洛谷 P6218 [USACO06NOV] Round Numbers S

    洛谷 P6218 [USACO06NOV] Round Numbers S 题目描述 如果一个正整数的二进制表示中,\(0\) 的数目不小于 \(1\) 的数目,那么它就被称为「圆数」. 例如,\(9 ...

  5. (java)剑指offer二维数组中的查找

    在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从 上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. pu ...

  6. Finding the Right EAV Attribute Table

    $customer = Mage::getModel('catalog/product'); $entity = $customer->getResource(); $attribute = M ...

  7. golang rpc demo

    RPC工作流程图 1.调用客户端句柄:执行传送参数 2.调用本地系统内核发送网络消息 3.消息传送到远程主机 4.服务器句柄得到消息并取得参数 5.执行远程过程 6.执行的过程将结果返回服务器句柄 7 ...

  8. windows操作报错:无法启动此程序,因为计算机中丢失api-ms-win-core-winrt-string-l1-1-0.dll

    在Windows上做提交svn操作时报错:无法启动此程序,因为计算机中丢失api-ms-win-core-winrt-string-l1-1-0.dll,如下图: 解决办法: 在 https://cn ...

  9. 团队作业4:第一篇Scrum冲刺博客(歪瑞古德小队)

    目录 一.Alpha阶段任务认领 二.明日任务安排 三.项目预期任务量 四.敏捷开发前的感想 五.团队期望 Author:歪瑞古德小队 Project:海岛漂流 集合贴:团队作业4:项目冲刺集合贴(歪 ...

  10. 区块链入门到实战(28)之Solidity – 介绍

    Solidity语言是一种面向合约的高级编程语言,用于在以太坊区块链网络上实现智能合约.Solidity语言深受c++.Python和JavaScript的影响,针对以太坊(Ethereum)虚拟机( ...