Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用特定示例理解C#中的委托和事件_C#_Events_Delegates - Fatal编程技术网

使用特定示例理解C#中的委托和事件

使用特定示例理解C#中的委托和事件,c#,events,delegates,C#,Events,Delegates,因此,我正处于理解事件和代表的阶段 我完全理解代理的用法。 关于委托,我唯一关心的是委托是否可以配置为使用与事件无关的函数如果是,如何为委托定义的函数编写逻辑?(我想这样的函数并没有什么意义,但最好知道。) 至于事件。。。我很难理解它。我的想法是,事件是一个函数,当代码中发生某些事情时执行。 但是,我不了解创建事件的过程。部分地 对于这个问题,我将使用Gary Willoughby的回答: 它贴在一个问题上,我试图从中理解整个主题 在上面的例子中我没有得到的: MyObject.OnMaximu

因此,我正处于理解事件和代表的阶段

我完全理解代理的用法。 关于委托,我唯一关心的是委托是否可以配置为使用与事件无关的函数如果是,如何为委托定义的函数编写逻辑?(我想这样的函数并没有什么意义,但最好知道。)

至于事件。。。我很难理解它。我的想法是,事件是一个函数,当代码中发生某些事情时执行。 但是,我不了解创建事件的过程。部分地

对于这个问题,我将使用Gary Willoughby的回答: 它贴在一个问题上,我试图从中理解整个主题

在上面的例子中我没有得到的:
MyObject.OnMaximum+=新的MyEventHandler(已达到最大值)
首先,如何创建委托的实例,并在需要2个变量时只传递1个变量?我肯定缺少什么…
关于这行的第二件事是,
new…()
实例被添加到
onmax
函数中,该函数位于
MyObject
中,它是
MyClass
-的一个实例,如果可以做这样的事情,那么
onmax
到底是什么?
它从来没有真正定义过

      if(OnMaximum != null) {
        OnMaximum(this, new MyEventArgs("You've entered " +
          value.ToString() +
          ", but the maximum is " +
          Maximum.ToString()));
      }
对于这一部分,调用了
onmax
,但它的逻辑从未在代码中的任何地方真正定义过,那么结果会是什么呢?显然,我猜应该是文本“You have enter……”,但我的问题是更具体地说,函数/事件接收到的值到底发生了什么?

为了清晰起见,我把所有问题都标成了粗体

另外,我知道这个问题一般已经发布了好几次。
请注意,此特定问题指的是另一位成员编写的答案,此处提出的问题针对此示例。这就是为什么在谷歌上找不到这样的答案。

不过,为了记录在案,我在发布之前确实搜索过,我也尝试过理解,但我想示例是我理解某些东西的最佳方式,尤其是在我缺乏英语CS词汇知识的情况下。

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

你看,所有的事件都是一个委托。实际上,老实说,它是一个委托集合,可能是
null

让我们举一个例子:

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;
另一方面,委托的工作方式与我们刚才描述的完全相同,但其工作方式更类似于函数指针。想象一下一个抽象的渲染器,我可以这样创建类:

public abstract class Renderer
{
    protected abstract void RenderImpl();
}
这意味着,我必须从该渲染中导出。但是如果渲染器接受了一个委托呢

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

    public Renderer(RenderDelegate) { /* ... */ }
}
我们现在正在分离组成部分

我在说什么?要么更好,要么不更好?就事件而言,我允许公众成为我们班的观察员。他们可以做出反应。在第二种情况下,我定义了一个用户提供的委托来执行小生境功能,同时我保留了大部分控制权

委托和活动基本上是一样的,但我们所做的设计选择决定了哪一个是合适的

为了说明你的其他观点,你举了一个事件与代表的很好的例子。如果我们更改上面的报警类,允许代理返回
true
false
,那么会发生什么

我们会让几个观察者返回真值,但谁是对的,我们如何检查他们

但是,沿着单代理路线。。。“渲染成功”或“渲染失败”。更改此单个委托并不是什么大问题。我们可以预测测试渲染器是否完成了工作:

if(!delegate_->Invoke())
    fallBackCode();
我们不能在活动中做到这一点。嗯,不可预测

更简单地说,当您想要广播某个事件,并让其他人在收到该事件后做某件事时,事件就在那里。炸弹爆炸了。。。跑开,躲起来,打电话给国民警卫队,关掉烤箱,或者躲起来

委托允许您在不更改模型的情况下更改功能(委托遵循签名!)。调用
List.Sort
就是一个很好的委托示例。那是一个代表。它有签名


但您也可以将它们用于更高级的事情,例如在不使用接口的情况下更改
呈现程序
类,以及能够提供用户定义的“代码片段”。我想这里最简单的类比应该是Win32中的所有者绘制控件。无需重写整个类,无需提供接口和编写大量代码。只需更改组合框中呈现项目的位。学员是您如何实现这一目标的好例子。

MSDN上的教程将回答您的所有问题:

代表们:


活动:

加油,伙计们!你们所有人都成功地将学员复杂化:)

我将尝试在这里留下一个提示:一旦我在Javascript中实现了jQueryAjax调用,我就理解了委托。例如:ajax.send(url、数据、successcallback、failcallback)是函数的签名。如您所知,它将数据发送到服务器URL,作为响应,可能是200OK或其他错误。如果发生任何此类事件(成功/失败),您希望执行一个函数。因此,这就像一个占位符的功能,能够提到成功或失败。 该占位符可能不太通用-它可能接受一组参数,并且可能/可能不返回值。这种占位符的声明,如果用C#完成,则称为DELEGATE!作为javascript函数而不是stri
class Program
    {
        static void Main(string[] args)
        {
            Parent p = new Parent();
        }
    }

    ////////////////////////////////////////////

    public delegate void DelegateName(string data);

    class Child
    {
        public event DelegateName delegateName;

        public void call()
        {
            delegateName("Narottam");
        }
    }

    ///////////////////////////////////////////

    class Parent
    {
        public Parent()
        {
            Child c = new Child();
            c.delegateName += new DelegateName(print);
            //or like this
            //c.delegateName += print;
            c.call();
        }

        public void print(string name)
        {
            Console.WriteLine("yes we got the name : " + name);
        }
    }