delegate vs event

本文通过两个实例详细解释了委托和事件在C#中的区别。事件为委托实例提供了一层抽象和保护,防止客户端重置委托及其调用列表,并且只能添加或移除目标。文章还探讨了使用委托和事件时可能遇到的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

What are the differences between delegate and an event

An event declaration adds a layer of abstraction and protection on the delegate instance. This protection prevents clients of the delegate from resetting the delegate and its invocation list and only allows adding or removing targets from the invocation list. 
To understand the differences you can look at 2 examples below:

Example with Delegate

First let's try to implement an "event trigger" by using "delegate" instead of "event". 
in this case, the example delegate Run is an Action - that is a kind of delegate that doesn't return a value.

  1. public class Animal
  2. {
  3. public Action Run {get; set;}
  4. public void RaiseEvent()
  5. {
  6. if (Run != null)
  7. {
  8. Run();
  9. }
  10. }
  11. }

To use the delegate, you should do something like this:

  1. Animal animal= new Animal();
  2. animal.Run += () => Console.WriteLine("I'm running");
  3. animal.Run += () => Console.WriteLine("I'm still running") ;
  4. animal.RaiseEvent();

This code works well but you could have some weak spots
For example, if I write this:

  1. animal.Run += () => Console.WriteLine("I'm running");
  2. animal.Run += () => Console.WriteLine("I'm still running");
  3. animal.Run = () => Console.WriteLine("I'm sleeping") ;

with the last line of code, I have overridden the previous behaviors just with one missing + (I have used = instead of +=)

Another weak spot is that every class which uses your Animal class can raise the Run event without calling the public RaiseEvent function, but with code snippet like:

  1. if (animal.Run != null)
  2. {
  3. animal.Run();
  4. }

To avoid these weak spots you can use events in c#.

Example with Event

Your "event version" of the Animal class will looks like:

  1. public class ArgsSpecial : EventArgs
  2. {
  3. public ArgsSpecial (string val)
  4. {
  5. Operation=val;
  6. }
  7. public string Operation {get; set;}
  8. }
  9. public class Animal
  10. {
  11. // Empty delegate. In this way you are sure that value is always != null
  12. // because no one outside of the class can change it.
  13. public event EventHandler<ArgsSpecial> Run = delegate{};
  14. public void RaiseEvent()
  15. {
  16. Run(this, new ArgsSpecial("Run faster"));
  17. }
  18. }

to call events

  1. Animal animal= new Animal();
  2. animal.Run += (sender, e) => Console.WriteLine("I'm running. My value is {0}", e.Operation);
  3. animal.RaiseEvent();

Differences:

1. You aren't using a public property but a public field. 
Using events, the compiler protects your fields from unwanted access 
2. Event can't be assigned directly. 
In this case, it is impossible to override the previous behaviors by using = instead of +=. 
3. No one outside of your class can raise the event. 
Even the Run event is public, a compiler error will occur if someone tries to raise the event with code snippet below:

  1. // Error: the event 'delegateEvent.Animal.Run' can only appear on the left hand side of += or -=
  2. // (except when used from within the type 'delegateEvent.Animal')
  3. animal.Run(animal, new ArgsSpecial("Run slower"));

4. Event can be included in an interface declaration, whereas a delegate field cannot.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值