Asa*_*saf 4 c# events delegates
所以我正在理解事件和代表.
我完全理解代表的用法.关于委托的唯一问题是代理是否可以配置为以任何方式使用与事件无关的函数... 如果是,我如何为委托定义的函数编写逻辑?(我想这个功能并没有太多意义,但知道它很好.)
至于事件......我很难理解它.我认为事件是在代码中发生某些事情时执行的函数.但是,我没有得到创建活动的过程.部分.
对于这个问题,我将使用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()));
}
Run Code Online (Sandbox Code Playgroud)
至于这部分,OnMaximum被调用,但它的逻辑从未真正定义在代码中的任何地方,那么结果会是什么呢?显然我猜它是"你输入............."的文字,但我的问题是更具体,功能/事件收到的值真正发生了什么?
为了清楚起见,我在BOLD中标记了所有问题.
PS,我知道这个问题一般都已发布过几次.
请注意,此特定问题是指其他成员撰写的答案,此处提出的问题仅适用于此示例.这就是为什么谷歌没有真正找到这样的答案的原因.
尽管如此,我在发布之前就进行了搜索,但我确实试图理解,但我想这些例子是我了解某些内容的最佳方式,尤其是当我对英语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;
}
Run Code Online (Sandbox Code Playgroud)
所有的event关键字都在这里给我们提供了添加和删除该事件的监听器的能力......
Alarm a = new Alarm();
a.OnAlert += myevent;
a.OnAlert += myotherevent;
Run Code Online (Sandbox Code Playgroud)
另一方面,代表虽然完全像我们刚才描述的那样工作,但更像是一个函数指针.想象一个抽象的渲染器,我可以这样做:
public abstract class Renderer
{
protected abstract void RenderImpl();
}
Run Code Online (Sandbox Code Playgroud)
这意味着,我必然会从该渲染中得出.但是如果那个渲染器拿了一个代表怎么办?
public abstract class Renderer
{
public delegate void RenderDelegate();
public Renderer(RenderDelegate) { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)
我们现在正在分离出构图.
我得到了什么?是好还是不好?在事件的情况下,我允许公众成为我班级的观察员.他们可以做出反应 在第二种情况下,我定义了一个用户提供的委托来执行利基功能,同时我保留了大部分控制权.
代表和活动大多是相同的 - 但我们制定的设计选择确定哪一个是合适的.
为了解决您的其他问题,您将提出一个很好的事件与代表的例子.如果我们要改变上述报警类别,允许委托返回true或false,然后会发生什么?
我们会让几个观察者返回真实,但谁是对的,我们如何检查它们?
然而,在单个代表路线下......"渲染成功"或"渲染失败".改变这个单一代表并不是一个问题.我们可以预测地测试我们的渲染器是否完成了这项工作:
if(!delegate_->Invoke())
fallBackCode();
Run Code Online (Sandbox Code Playgroud)
我们不能用事件真正做到这一点.嗯,不可预测.
更简单地说,当你想要播放某些内容并让其他人在收到该事件时做某事时,就会有事件发生.炸弹爆炸了......跑,躲起来,打电话给国民警卫队,关掉烤箱,或者躲开并盖住.
代表允许您在不更改模型的情况下更改功能(代表遵循签名!).代表的一个很好的例子就是你打电话的时候List<T>.Sort.那是代表.它有一个签名.
但是您也可以将它们用于更高级的事情,例如在Renderer不使用接口的情况下更改类,以及能够提供用户定义的"片段".我想这里最简单的类比是Win32中的所有者绘制控件.无需覆盖整个类,无需提供接口并编写大量代码.只需更改在组合框中呈现项目的位.代表们是您如何实现这一目标的绝佳范例.