What are the differences between delegates and events?

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 this 2 examples

Example with Delegates (in this case, an Action - that is a kind of delegate that doesn't return a value)

public class Animal
{
    public Action Run {get; set;}

    public void RaiseEvent()
    {
        if (Run != null)
        {
            Run();
        }
    }
}

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

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

This code works well but you could have some weak spots.

For example, if I write this:

animal.Run += () => Console.WriteLine("I'm running");
animal.Run += () => Console.WriteLine("I'm still running");
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 RaiseEvent just calling it animal.RaiseEvent().

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

Your Animal class will change in this way:

public class ArgsSpecial : EventArgs
{
    public ArgsSpecial (string val)
    {
        Operation=val;
    }

    public string Operation {get; set;}
} 

public class Animal
{
    // Empty delegate. In this way you are sure that value is always != null 
    // because no one outside of the class can change it.
    public event EventHandler<ArgsSpecial> Run = delegate{} 

    public void RaiseEvent()
    {  
         Run(this, new ArgsSpecial("Run faster"));
    }
}

to call events

 Animal animal= new Animal();
 animal.Run += (sender, e) => Console.WriteLine("I'm running. My value is {0}", e.Operation);
 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. Events can't be assigned directly. In this case, it won't give rise to the previous error that I have showed with overriding the behavior.
  3. No one outside of your class can raise the event.
  4. Events can be included in an interface declaration, whereas a field cannot

Notes:

EventHandler is declared as the following delegate:

public delegate void EventHandler (object sender, EventArgs e)

it takes a sender (of Object type) and event arguments. The sender is null if it comes from static methods.

This example, which uses EventHandler<ArgsSpecial>, can also be written using EventHandler instead.

Refer here for documentation about EventHandler


In addition to the syntactic and operational properties, there's also a semantical difference.

Delegates are, conceptually, function templates; that is, they express a contract a function must adhere to in order to be considered of the "type" of the delegate.

Events represent ... well, events. They are intended to alert someone when something happens and yes, they adhere to a delegate definition but they're not the same thing.

Even if they were exactly the same thing (syntactically and in the IL code) there will still remain the semantical difference. In general I prefer to have two different names for two different concepts, even if they are implemented in the same way (which doesn't mean I like to have the same code twice).