c# - 使用特定示例了解 C# 中的委托(delegate)和事件

标签 c# events delegates

所以我要了解事件和委托(delegate)。

我大致了解委托(delegate)的用法。 关于委托(delegate),我唯一关心的是是否可以将委托(delegate)配置为与以任何方式与事件无关的函数一起工作...如果是,我如何编写委托(delegate)定义函数的逻辑? (我想这样的功能并没有多大意义,但知道它很好。)

至于事件……我很难理解。我认为事件是一个函数,当代码中发生某些事情时会执行该函数。 但是,我不知道创建事件的过程。部分。

对于这个问题,我将使用 Gary Willoughby 的回答:https://stackoverflow.com/a/803528/1104766 它是在一个问题上发布的,我试图从中理解整个主题。

我在上面的例子中没有得到的:
MyObject.OnMaximum += new MyEventHandler(MaximumReached);
首先,如何创建一个委托(delegate)实例,并在它需要 2 个变量时只传递 1 个变量?一定有什么我遗漏的...
关于这一行的第二件事是 new ...() 实例被添加到驻留在 中的 OnMaximum 函数中MyObjectMyClass 的一个实例 - 如果可以完成这样的事情,OnMaximum 到底是什么? 它也从未真正定义过!

      if(OnMaximum != null) {
        OnMaximum(this, new MyEventArgs("You've entered " +
          value.ToString() +
          ", but the maximum is " +
          Maximum.ToString()));
      }

至于这部分,OnMaximum 被调用,但它的逻辑从未在代码中的任何地方真正定义,那么结果会是什么?显然我猜它会是文本“你已经输入......”但我的问题是更具体,函数的值到底发生了什么/事件接收?

为了清楚起见,我用粗体标记了我所有的问题。

P.S,我知道这个问题一般已经发布了几次。
请注意,这个特定问题是指另一个成员写的答案,这里提出的问题是特定于这个例子的。这就是为什么在谷歌中无法真正找到此类答案的原因。 不过郑重声明,我在发帖前进行了搜索,并尝试理解,但我想示例是我理解某些内容的最佳方式,尤其是在我缺乏英语 CS 词汇知识的情况下。

最佳答案

我想你可能是语法糖过量了!

你看,一个事件就是一个委托(delegate)。实际上,老实说,它是一个可能是 null 的委托(delegate)集合。 .

举个例子:

public class Alarm
{
    public delegate void AlarmEvent();

    // my secret stuff

    // raise it!
    public void Ring()
    {
        if(OnAlert != null)
           OnAlert();
    }

    public event AlarmEvent OnAlert;
}

event 关键字在这里为我们提供的是为该事件添加和删除监听器的能力...

Alarm a = new Alarm();
a.OnAlert += myevent;
a.OnAlert += myotherevent;

另一方面,委托(delegate)虽然像我们刚才描述的那样工作,但更类似于函数指针。想象一个抽象渲染器,我可以这样创建类:

public abstract class Renderer
{
    protected abstract void RenderImpl();
}

这意味着,我必须从该渲染中派生。但是,如果该渲染器接受委托(delegate)怎么办?

public abstract class Renderer
{
    public delegate void RenderDelegate();

    public Renderer(RenderDelegate) { /* ... */ }
}

我们现在正在分离组合。

我在说什么?是好还是不好?在事件的情况下,我允许公众成为我类(class)的观察员。他们可以使用react。在第二种情况下,我定义了一个用户提供的委托(delegate)来执行一个小众功能,同时我保留了大部分控制权。

委托(delegate)和事件在很大程度上是一回事 - 但我们做出的设计选择决定了哪一个是合适的。

为了解决您的其他问题,您举了一个很好的事件与委托(delegate)的例子。如果我们要更改上面的警报类,以允许委托(delegate)返回 truefalse ,然后会发生什么?

我们会让几个观察者返回 true,但谁是正确的以及我们如何检查它们?

然而,沿着单委托(delegate)路线...“渲染成功”或“渲染失败”。改变这个单一的委托(delegate)并不是什么大问题。我们可以预测地测试我们的渲染器是否完成了工作:

if(!delegate_->Invoke())
    fallBackCode();

我们真的不能用事件来做到这一点。嗯,出乎意料。

更简单地说,当您想要广播某些内容并让其他人在收到该事件后做某事时,就会出现事件。炸弹爆炸了……跑,躲起来,调用国民 guard 队,关掉 toastr ,或者躲起来躲起来。

委托(delegate)允许您在不更改模型的情况下更改功能(委托(delegate)遵循签名!)。委托(delegate)的一个很好的例子,就是当你调用 List<T>.Sort 时.那是一个委托(delegate)。它有一个签名。

但您也可以将它们用于更高级的事情,例如更改 Renderer类而不求助于接口(interface),并且能够提供用户定义的“片段”。我想这里最简单的类比是 Win32 中的所有者描述控件。不需要重写整个类,不需要提供接口(interface),写很多代码。只需更改呈现组合框中项目的位。委托(delegate)是您如何实现这一目标的绝佳示例。

关于c# - 使用特定示例了解 C# 中的委托(delegate)和事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14093325/

相关文章:

c# - .vs 文件夹到 visual studio 2015 中的源代码管理?

C# 创建一个代表台湾日期的 DateTime 对象 2 月 29 日 101(闰日)

javascript - 为同一页面上的多个 video.js 播放器添加事件监听器

c# - 在同一类上启用 EAP 和 async/await

javascript - 按下回车键时,onClick 不会仅通过一个输入触发

javascript - MVC - 下载文件前后加载屏幕/禁用按钮

c# - 委托(delegate),多个订阅者的方法调用

delegates - Pharo Smalltalk 中的委托(delegate)团

c++ - 在 QListWidget 的 QStyledItemDelegate 中,如何绘制所选项目以匹配标准列表?

c# - Windows 8 空白应用 + DEP0700 错误