如何使用委托调用事件?我可以这样填写下面的空白吗? [英] How to use the delegate calls the event? Can I fill in the blanks below like this?

查看:76
本文介绍了如何使用委托调用事件?我可以这样填写下面的空白吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

public delegate void Operate(); 
public class UserControlBase : UserControl 
{ 
    public event Operate OnNew; 
    private void toolBar_ButtonClick(object sender,EventArgs e) 
    { 
        if(e.Button.Equals(BtnNew)) 
        { 
           //Filled in the following code to call the trigger OnNew event.
           --------;(1 point)
           --------  ;(1 point)
        } 
    } 
}



我是这样写的,对吗?



I wrote it like this,was it right?

if (OnNew != null)
  OnNew(sender, e);

推荐答案

相当多-的确有一个小的窗口"供出错.这是我使用的模板:
Pretty much - it does leave a small "window" for error though. Here is the template I use:
public event EventHandler Changed;

protected virtual void OnChanged(EventArgs e)
   {
   EventHandler eh = Changed;
   if (eh != null)
      {
      eh(this, e);
      }
   }

private void DoSomethingToChangeData()
   {
   OnChanged(null);
   }

唯一真正的变化是,它将在检查之前将委托加载到临时引用eh中.如果您不这样做,那么(在检查和执行之间)可能会删除处理程序(这是极不可能的).这可能会在代码中出现空引用异常的间歇性问题,该异常会检查空引用...




我已经看过这种在空检查之前分配给EventHandler的方式,并且想知道与仅仅相比,这是否确实有可能带来不同:

The only real change is that it loads the delegate into a temporary reference eh before it checks. If you don''t then there is the (admittedly unlikely) possibility that the handler could be removed between the check and the execution. This could give an intermittent problem with a null reference exception in code that checks for null references...




"I''ve seen this way of assigning to an EventHandler before the null check, and wondered if that really does make a possible difference compared to just:

protected virtual void OnChanged(EventArgs e)
{
   if (Changed != null)
   {
     Changed(this, e);
   }
}


如果我检查(Changed == null)的值,即使在Form Load事件中,也没有任何东西订阅"到该事件之前,它似乎总是"true".

如果您想多说一些为什么分配给临时引用可以防止错误,那将不胜感激."



你要记住的是


If I examine the value of (Changed == null), even in a Form Load event before anything has "subscribed" to the event: it seems to be always ''true.

If you care to say a bit more about why assigning to temporary reference would prevent an error, that would be appreciated."



What you have to remember is that

If (Changed != null) Change(this, null);

不是一条指令.执行后,它会评估为一系列机器"指令:
1)加载值已更改"
2)与值"null"进行比较
3)如果相同则跳转到labelatend
5)加载"this"的值作为参数
6)将"null"的加载值作为参数
7)加载值已更改".
8)在加载的值处调用子例程
9)Labelatend-从这里继续.

问题在于,在两个负载之间被清除(通过不同的线程,甚至是内核)"Changed"的值的可能性非常小.如果发生这种情况,那么您将得到一个空引用错误.

如果将其加载到临时目录中,那么这种可能性很小,对性能的影响很小.

这只是防御性编程-假设最糟糕的情况并进行检查! :laugh:

is not a single instruction. When it is executed it evaluates to a sequence of "machine" instructions:
1) Load value of "Changed"
2) Compare with value "null"
3) Jump if the same to labelatend
5) Load value of "this" as parameter
6) Load value of "null" as parameter
7) Load value of "Changed".
8) Call subroutine at loaded value
9) Labelatend - continue from here.

The problem is that there is a very, very small chance that the value of "Changed" could have been cleared (by a different thread, or even core) between the two loads. If that happens, then you get an null reference error.

If you load it into a temporary, then that tiny possibility goes away, for a very minimal performance hit.

It''s just defensive programming - assume the worst and check for it! :laugh:


这篇关于如何使用委托调用事件?我可以这样填写下面的空白吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆