2012-03-01 62 views
2

如果某个类在其方法中触发事件,则该类不必知道订阅其事件的人或谁。如果有任何用户,这也不重要。处理可能没有任何订阅者的事件

在下面的代码中,如果没有任何订阅者发生OnTrigger事件,则会发生异常。

public class EventTrigger 
{ 
    public static void Main(string[] args) 
    { 
     (new EventTrigger()).Trigger(); 
    } 

    public delegate void Delegate1(); 
    public event Delegate1 OnTrigger; 

    void Trigger() 
    { 
     OnTrigger(); 
    } 
} 

我可以这样称呼事件;

​​

但它对我来说似乎很奇怪,因为triggerer不必知道订阅。

我的问题是:

我一定要检查,如果事件引用为null,每当我使用它。

+1

这里是关于这个主题的一个有趣的讨论:http://stackoverflow.com/questions/248072/evil-use-of-extension-methods – ken 2012-03-01 16:44:15

+0

我并不孤单在宇宙中。这让我感觉很好。但我认为这也不是一个好方法。不是因为它是通过扩展方法完成的。因为它也需要更多的键盘输入并且变得更加脏。 – 2012-03-01 20:00:51

回答

2

如果你初始化OnTrigger那么你不必做检查。 例如

public event Action OnTrigger = delegate { }; 

是'delegate {}“实例化一个新的对象,这就是为什么这可以让你忽略'null'检查。

'delegate {}“所以,如果你希望它返回一个字符串(你需要的,如果Delegate1返回一个字符串)没有返回,那么你只需添加'return“”;”如:

public event Action OnTrigger = delegate { return string.Empty; }; 

我应该补充说的是,这样做是不好的做法,以避免空检查,因为这是一个懒惰的人。有些代码仍然可以将事件设置为null,'OnTrigger = null'会破坏你的代码。而当谈到(德)序列化它不会工作。

+0

谢谢。我有两个问题: 1st。 “委托{}”;“初始化一个对象?它返回什么? 2nd。我如何处理返回值的委托?像这样: public delegate string Delegate1(); 公共事件Delegate1 OnTrigger = delegate {}; – 2012-03-01 17:50:11

+0

我已经更新了答案 – Terkel 2012-03-01 20:35:18

+0

将一个事件初始化为包含一个空的订阅者有点难懂,因为'Delegate.Combine'和'Delegate.Remove'将代理添加到任何内容或从中减去委托要快得多他们正在处理其他场景,'Delegate.Invoke'处理非合并委托的开销少于合并委托的开销(并且跳过空委托的调用比调用虚委派的速度快)。如果预期的用户数量大于1,那么添加一个空的委托可能不会太糟糕,但是如果预计最多只有一个用户,这是浪费的。 – supercat 2012-03-02 17:26:53

1

触发器不必知道个别订阅者,但它确实需要了解订阅。您必须每次都进行空检查或使用西蒙建议的解决方法。