4

所以我正处于理解事件和代表的地步。

我总体了解代表的用法。关于委托,我唯一担心的是委托是否可以配置为使用与事件无关的函数......如果可以,我如何为委托定义的函数编写逻辑?(我想这样的功能并没有多大意义,但很高兴知道。)

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

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

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

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

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

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

PS,我知道这个问题通常已经发布了几次。
请注意,此特定问题是指另一位成员撰写的答案,此处提出的问题是针对此示例的。这就是为什么在谷歌中找不到这样的答案。
不过,为了记录,我在发布之前进行了搜索,并且确实尝试理解,但我想示例是我理解某些东西的最佳方式,尤其是在我缺乏英语 CS 词汇知识的情况下。

4

4 回答 4

7

我认为您可能患有过量的语法糖!

你看,一个事件就是一个代表。实际上,老实说,它可能是代表的集合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) { /* ... */ }
}

我们现在正在分离组合物。

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

代表和活动大多是同一件事——但我们所做的设计选择决定了哪一个是合适的。

为了解决您的其他观点,您提出了一个很好的事件与代表的例子。如果我们要更改上面的警报类,允许委托返回trueor false,那么会发生什么?

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

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

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

我们真的不能用事件来做到这一点。嗯,不可预测。

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

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

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

于 2012-12-30T18:34:27.310 回答
1

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

代表: http: //msdn.microsoft.com/en-us/library/aa288459 (v=vs.71).aspx

事件: http: //msdn.microsoft.com/en-us/library/aa645739 (v=vs.71).aspx

于 2012-12-30T18:44:14.930 回答
0
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);
        }
    }
于 2014-09-20T17:17:54.073 回答
0

拜托了伙计们!你们所有人都成功地使代表复杂化了:)!

我将尝试在这里留下一个提示:一旦我意识到 Javascript 中的 jquery ajax 调用,我就理解了代表。例如: ajax.send(url, data, successcallback, failcallback) 是函数的签名。如您所知,它将数据发送到服务器 URL,作为响应,它可能是 200OK 或其他错误。如果发生任何此类事件(成功/失败),您需要执行一个函数。因此,这就像一个函数的占位符,可以在成功或失败中提及。该占位符可能不是很通用 - 它可能接受一组参数并且可能/可能不会返回值。这种占位符的声明,如果在 C# 中完成,则称为代表!由于 javascript 函数对参数数量不严格,您只会将它们视为 GENERIC 占位符......但 C# 有一些 STRICT 声明......归结为 DELEGATE 声明!

希望能帮助到你!

于 2015-04-27T09:14:58.177 回答