C# 从1到Core--委托与事件(一)

简介:  委托与事件在C#1.0的时候就有了,随着C#版本的不断更新,有些写法和功能也在不断改变。本文温故一下这些改变,以及在NET Core中关于事件的一点改变。

一、C#1.0 从委托开始

1. 基本方式

  什么是委托,就不说概念了,用例子说话。

  某HR说他需要招聘一个6年 .NET5 研发经验的“高级”工程师,他想找人(委托)别人把这条招聘消息发出去。这样的HR很多,所以大家定义了一个通用的发消息规则:

public delegate string SendDelegate(string message);

这就像一个接口的方法,没有实际的实现代码,只是定义了这个方法有一个string的参数和返回值。所有想发招聘消息的HR只要遵守这样的规则即可。


委托本质上是一个类,所以它可以被定义在其他类的内部或外部,根据实际引用关系考虑即可。本例单独定义在外部。


为HR定义了一个名为HR的类:

public class HR
{
    public SendDelegate sendDelegate;
    public void SendMessage(string msg)
    {
        sendDelegate(msg);
    }
}

HR有一个SendDelegate类型的成员,当它需要发送消息(SendMessage)的时候,只需要调用这个sendDelegate方法即可。而不需要实现这个方法,也不需要关心这个方法是怎么实现的。


当知道这个HR需要发送消息的时候,猎头张三接了这个帮忙招人的工作。猎头的类为Sender,他有一个用于发送消息的方法Send,该方法恰好符合众人定义的名为SendDelegate的发消息规则。这有点像实现了一个接口方法,但这里不要求方法名一致,只是要求方法的签名一致。

public class Sender
{
    public Sender(string name)
    {
        this.senderName = name;
    }
    private readonly string senderName;
    public string Send(string message)
    {
        string serialNumber = Guid.NewGuid().ToString();
        Console.WriteLine(senderName + " sending....");
        Thread.Sleep(2000);
        Console.WriteLine("Sender: " + senderName + " , Content: " + message + ", Serial Number: "  + serialNumber);
        return serialNumber;
    }
}

猎头帮助HR招人的逻辑如下:

public void Test()
{
    //一个HR
    HR hr = new HR();
    //猎头张三来监听,听到HR发什么消息后立刻传播出去
    Sender senderZS = new Sender("张三");
    hr.sendDelegate = senderZS.Send;
    //HR递交消息
    hr.SendMessage("Hello World");
}

猎头将自己的发消息方法“赋值”给了HR的SendDelegate方法,为什么可以“赋值”? 因为二者都遵守SendDelegate规则。 就像A和B两个变量都是int类型的时候,A可以赋值给B一样。


这就是一个简单的委托过程,HR将招人的工作委托给了猎头,自己不用去做招人的工作。


但经常一个招聘工作经常会有多个猎头接单,那就有了多播委托。

2. 多播委托

看一下下面的代码:

1.public void Test()
{
    //一个HR
    HR hr = new HR();
    //猎头张三来监听,听到HR发什么消息后立刻传播出去
    Sender senderZS = new Sender("张三");
    hr.sendDelegate = senderZS.Send;
    //快嘴李四也来了
    Sender senderLS = new Sender("李四");
    hr.sendDelegate += senderLS.Send;
    //HR递交消息
    hr.SendMessage("Hello World");
}

与之前的代码改变不大, 只是添加了李四的方法绑定,这样HR发消息的时候,张三和李四都会发出招人的消息。


这里要注意李四绑定方法的时候,用的是+=而不是=,就像拼接字符串一样,是拼接而不是赋值,否则会覆盖掉之前张三的方法绑定。


对于第一个绑定的张三,可以用=号也可以用+=(记得之前好像第一个必须用=,实验了一下现在二者皆可)。


这同时也暴露了一些问题:


如果后面的猎头接单的时候不小心(故意)用了=号, 那么最终前面的人的绑定都没有了,那么他将独占这个HR客户,HR发出的消息只有他能收到。

可以偷偷的调用猎头的hr.sendDelegate

public void Test()
{
    //一个HR
    HR hr = new HR();
    //大嘴张三来监听,听到HR发什么消息后立刻传播出去
    Sender senderZS = new Sender("张三");
    //hr.sendDelegate -= senderZS.Send; //即使未进行过+=  直接调用-=,也不会报错
    hr.sendDelegate += senderZS.Send;
    //快嘴李四也来了
    Sender senderLS = new Sender("李四");
    hr.sendDelegate += senderLS.Send;
    //移除
    //hr.sendDelegate -= senderZS.Send;
    //风险:注意上面用的符号是+=和-=   如果使用=,则是赋值操作,
    //例如下面的语句会覆盖掉之前所有的绑定
    //hr.sendDelegate = senderWW.Send;
    //HR递交消息
    hr.SendMessage("Hello World");
    //风险:可以偷偷的以HR的名义偷偷的发了一条消息    sendDelegate应该只能由HR调用   
    hr.sendDelegate("偷偷的发一条");
}


目录
相关文章
|
22天前
|
C#
c# Gridview 点击checkbox 触发的事件
c# Gridview 点击checkbox 触发的事件
|
22天前
|
C#
C# Dev解决gridview1_SelectionChanged和gridview1_RowCellClick事件触发两次等问题
C# Dev解决gridview1_SelectionChanged和gridview1_RowCellClick事件触发两次等问题
C# Dev解决gridview1_SelectionChanged和gridview1_RowCellClick事件触发两次等问题
|
22天前
|
C#
C# 禁止ComboBox滚动事件细谈
C# 禁止ComboBox滚动事件细谈
|
2月前
|
开发框架 中间件 .NET
C# .NET面试系列七:ASP.NET Core
## 第一部分:ASP.NET Core #### 1. 如何在 controller 中注入 service? 在.NET中,在ASP.NET Core应用程序中的Controller中注入服务通常使用<u>依赖注入(Dependency Injection)</u>来实现。以下是一些步骤,说明如何在Controller中注入服务: 1、创建服务 首先,确保你已经在应用程序中注册了服务。这通常在Startup.cs文件的ConfigureServices方法中完成。例如: ```c# services.AddScoped<IMyService, MyService>(); //
65 0
|
2月前
|
开发框架 安全 .NET
C# .NET面试系列三:集合、异常、泛型、LINQ、委托、EF!
<h2>集合、异常、泛型、LINQ、委托、EF! #### 1. IList 接口与 List 的区别是什么? IList 接口和 List 类是C#中集合的两个相关但不同的概念。下面是它们的主要区别: <b>IList 接口</b> IList 接口是C#中定义的一个泛型接口,位于 System.Collections 命名空间。它派生自 ICollection 接口,定义了一个可以通过索引访问的有序集合。 ```c# IList 接口包含一系列索引化的属性和方法,允许按索引访问、插入、移除元素等。 由于是接口,它只定义了成员的契约,而不提供具体的实现。类似于 IEnumera
159 2
|
4月前
|
存储 C# C++
C#进阶-委托(Delegrate)
类似于 C 或 C++ 中函数的指针,委托是C#的函数指针,是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。本篇文章我们将讲解C#里委托的类型及如何使用。委托的语法第一次接触难免感到陌生,最好的学习方式就是在项目中多去使用,相信会有很多感悟。
27 0
|
5月前
|
Java C# C++
【从Java转C#】第八章:委托、lambda、事件
【从Java转C#】第八章:委托、lambda、事件
|
5月前
|
C#
C#中的委托
C#中的委托
20 0
|
6月前
|
存储 开发框架 .NET
c#委托详解
委托是一种能够将方法作为参数传递、存储方法并且调用方法的类型,它可以让我们写出更加灵活和可扩展的代码。委托通常用于回调 (Callback) 机制,比如在事件处理、异步编程、LINQ 查询等场景中常常会使用委托。它可以将方法作为参数传递给其他方法,从而在需要的时候执行该方法。
28 2