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