Dee*_*Raj 8 .net c# events delegates
我知道事件总是与代表联系在一起.但是,我错过了一些事件的核心用法,并试图理解这一点.
我创建了一个简单的事件程序,如下所示,它工作得很好.
namespace CompleteRef3._0
{
delegate void someEventDelegate();
class EventTester
{
public event someEventDelegate someEvent;
public void doEvent()
{
if (someEvent != null) someEvent();
}
}
class Program
{
static void EventHandler1()
{
Console.WriteLine("Event handler 1 called..");
}
static void EventHandler2()
{
Console.WriteLine("Event handler 2 called..");
}
static void EventHandler3()
{
Console.WriteLine("Event handler 3 called..");
}
static void Main(string[] args)
{
EventTester evt = new EventTester();
evt.someEvent += EventHandler1;
evt.someEvent += EventHandler2;
evt.someEvent += EventHandler3;
evt.doEvent();
Console.ReadKey();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我用委托替换了事件声明.那就是我替换了行公共事件someEventDelegate someEvent; 与someEventDelegate someEvent; 在上面的程序中,我仍然得到相同的结果.现在,我很困惑为什么我们需要使用事件,如果它只能由Delegates实现.事件的真正用途是什么?
没有事件的修改程序如下 -
namespace CompleteRef3._0
{
delegate void someEventDelegate();
class EventTester
{
someEventDelegate someEvent;
public void doEvent()
{
if (someEvent != null) someEvent();
}
}
class Program
{
static void EventHandler1()
{
Console.WriteLine("Event handler 1 called..");
}
static void EventHandler2()
{
Console.WriteLine("Event handler 2 called..");
}
static void EventHandler3()
{
Console.WriteLine("Event handler 3 called..");
}
static void Main(string[] args)
{
EventTester evt = new EventTester();
evt.someEvent += EventHandler1;
evt.someEvent += EventHandler2;
evt.someEvent += EventHandler3;
evt.doEvent();
Console.ReadKey();
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
事件的主要目的是防止订户相互干扰.如果您不使用活动,您可以:
通过重新分配委托(而不是使用+ =运算符)替换其他订户,清除所有订户(通过将委托设置为null),通过调用委托向其他订户广播.
来源:C#in a Nutshell
想象一下,你有3个订阅者对你的someEvent感兴趣.他们订阅了这样的:
客户1
EventTester evt = new EventTester();
evt.someEvent += Client1Handler1;
evt.someEvent += Cleint1Handler2;
Run Code Online (Sandbox Code Playgroud)
客户2
EventTester evt = new EventTester();
evt.someEvent += Client2Handler1;
evt.someEvent += Client2Handler2;
Run Code Online (Sandbox Code Playgroud)
客户3
EventTester evt = new EventTester();
evt.someEvent += Client2Handler1;
evt.someEvent += Client2Handler2;
Run Code Online (Sandbox Code Playgroud)
现在想象另一个客户端这样做:
EventTester = null;
Run Code Online (Sandbox Code Playgroud)
客户端1,2和3将不会收到任何事件,因为您有以下代码行:
if (someEvent != null) someEvent();
Run Code Online (Sandbox Code Playgroud)
上面的代码行没有任何问题,但是使用委托有问题.
阿列克谢指出的另一个问题是:
someEvent = new someEventDelegate(EventHandler2)
Run Code Online (Sandbox Code Playgroud)
如果您有一个event客户端和其中一个客户端尝试了上述操作,则不会允许它们出现编译错误,如下所示:
当然,您可以使用委托,因为在幕后,事件是包装委托的构造.
但是使用事件而不是委托的基本原理与使用属性而不是字段相同 - 数据封装.直接暴露字段(无论它们是什么 - 原始字段或委托)是不好的做法.
顺便说一句,您public在委托字段之前错过了一个关键字,以便在第二个代码段中实现.
使用第二个片段的另一个"顺便说一句":对于代表,您应该使用Delegate.Combine而不是"+ =".
| 归档时间: |
|
| 查看次数: |
7482 次 |
| 最近记录: |