locked
Difference between delegate and event RRS feed

  • Question

  • I'm reviewing some writtings on the difference between delegate and event.

    I can't figure out following comment.

    A delegate is declared outside a class whereas, an event is declared inside a class
    Can anybody explain more detail about this?

    Sunday, March 15, 2020 11:55 PM

Answers

  • If you are interested in differences, check the next one too.

    Imagine that you have a class that includes two data members and a function:

    class Class1

    {

           public EventHandler d;

           public event EventHandler e;

     

           void f()

           {

           }

    }

     

    When you write the code inside the f function, there is no difference between d and e. You can apply various operations that are defined for delegates, such as ‘+=’, ‘-=’, ‘=’, ‘=null’, ‘==’, ‘( )’, etc.

    If you are outside this class, you can use any operation for d, but for e you can only execute ‘+=’ and ‘-=’. I.e. event introduces a limitation, even in derived classes.

    • Edited by Viorel_MVP Monday, March 16, 2020 8:38 PM
    • Marked as answer by Jeff0803 Sunday, March 22, 2020 12:12 AM
    Monday, March 16, 2020 8:17 PM

All replies

  • I think a good way to explain that is that a class is exposing an Event, such that delegates from outside that class can perform some action when the delegate is notified (by the class) that the Event took place.

    The following example/explanation is taken from my blog post: https://geek-goddess-bonnie.blogspot.com/2010/03/custom-events.html

    Say you have a custom UserControl class that you need to have raise an event when, for example, a user types "FOO" in a textbox that is on the Control.

    Minimally, in your UserControl class, you need the following things:

    // First you must specify the event that you will be raising:
    
    public event EventHandler MyFooBar;
    
    // Then, when you need to fire the event in your UserControl, do this:
    if (this.MyTextBox.Text == "FOO")
        this.OnMyFooBar(new EventArgs());
    
    // Lastly, this raises the MyFooBar event:
    protected virtual void OnMyFooBar(EventArgs e)
    {
        if (MyFooBar != null)
            MyFooBar(this, e);
    }

    So, there's your Event and it's defined in a class (the custom UserControl);

    Then your Form has an instance of your custom UserControl on it. The Form needs to have a delegate so that the Form can be notified by the custom UserControl when something happens.

    One could use an anonymous delegate for this purpose:

    this.oMyControl.MyFooBar += delegate
    {
        // whatever your code needs to be, such as
        MessageBox.Show("FOO was specified!");
    };
    

    Or, another way is like this (the System.EventHandler is the delegate):

    this.oMyControl.MyFooBar += new System.EventHandler(this.oMyControl_MyFooBarHandler);
    
    private void oMyControl_MyFooBarHandler(object sender, System.EventArgs e)
    {
        // whatever your form code needs to be, such as:
        MessageBox.Show("FOO was specified!");
    }

    Hope that helps!  =0)

    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Monday, March 16, 2020 12:41 AM
  • Hi Jeff,

    Thank you for posting here.

    There is no restriction on the location of a delegate. It can be declared inside the class or outside the class. But events must be declared inside the class.

    Events exist based on delegates. Delegates can bind methods. When an event is triggered, the program executes the method.

    Here is a code example.

        public delegate string TestHander(string str);
        class Program
        {
            event TestHander TestEvent;
            static void Main(string[] args)
            {
                Program program = new Program();
                program.TestEvent += new TestHander(program.Dowork);
                string res = program.TestEvent("Timon");
    
                Console.WriteLine(res);
                Console.ReadKey();
            }
    
           public string Dowork(string str) 
            {
                return "DoWork Hello: " + str;
            }
        }

    Regarding delegation and events, you can find a lot of detailed explanations on Google.

    Hope this could be helpful.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Monday, March 16, 2020 5:12 AM
  • As Timon mentioned, that comment is wrong. A delegate can be declared anywhere because it is a type. An event is a member of a class. While related, they are not the same thing. Delegates are simply type definitions from other languages. A delegate defines the signature of a function. This allows function arguments (or functors in other languages). Function arguments allow a function to be passed to another function as data. As an example.

    //Call foo
    var data = Foo();
    
    //Pass the function foo to another function so it may be able to call the function itself
    CallFoo(foo);

    Notice the syntactical difference. Function names with parens are function calls. The function is called at that point in the code and whatever result is returned back to the caller. With function arguments only the function name is specified (no parens or arguments). The function (object) is passed to the underlying function and it may at some point call the function. This is what we mean by function arguments - passing functions as arguments/data to be called by other functions.

    void CallFoo ( ? function )
    {
       if (someCondition)
          function();
    }

    For this to work we still need strong type checking. After all you cannot call a function unless you know what arguments it accepts and what data it returns (if any). Therefore you need to specify the type. But a normal type like int or string won't work as you have to capture the parameter types and return type of the function. Hence we use a type definition.

    public void SomeFunction ( );

    That is a delegate, a function type definition. Any function that matches the above signature can be used. Since this a type definition we can declare variables of that type, use them in parameters or as return types. They are just regular types.

    The term delegate comes from the implementation that .NET uses to get function objects to work. In order to call a function you need to know the function name and the instance it is tied to. After all if you pass `Foo` to another caller and `Foo` is an instance member then the instance it is applied to is needed as well. The type `Delegate` (or a derived type actually) is used to wrap the necessary information to properly call the function you're passing with the instance it is associated with. The compiler is responsible for generating this logic correctly for you but in advanced cases you can declare it yourself.

    //Not real code...
    var delegate = new Delegate(this, Foo);
    CallFoo(delegate);
    
    void CallFoo ( delegate )
    {
       delegate.Invoke(); // instance.Foo()
    }
    
    
    Events are just a mechanism to notify interested people about something happening. In order for this to work you have to be able to call functions in other code. For that we're back to function arguments and hence delegates. So the eventing infrastructure needs delegates to work but delegates are useful outside of just events. Events would simply be the earliest usage of delegates.


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, March 16, 2020 2:08 PM
  • A delegate can be declared anywhere because it is a type.

    This is the right answer to the OP's question, although I'd say a delegate is a "programmer-defined type definition and is strictly for defining a function signature as a type."  Delegates can be declared anywhere but inside a function (and technically you could rig a lambda expression to make a delegate in a function body).  They can be inside a namespace or inside a class or struct.  No matter where you put a delegate, that location is just organizational.  You don't need an instance of the delegate's container to reference or declare an object of the delegate-defined type.

    An event then is just an instance of a delegate-defined type.  It's a data field, so it can only go in classes or structs (or again you can rig an event inside a function body but that's under the topic of lambdas) because namespaces can't contain data fields.

    Neither the delegate or the event are implementations of the function-type represented by the delegate.  You have to write the function with the compatible signature, which then can be cast to the delegate-defined type or added to an event's consumer list.


    Before you can learn anything new you have to learn that there's stuff you don't know.

    Monday, March 16, 2020 5:08 PM
  • If you are interested in differences, check the next one too.

    Imagine that you have a class that includes two data members and a function:

    class Class1

    {

           public EventHandler d;

           public event EventHandler e;

     

           void f()

           {

           }

    }

     

    When you write the code inside the f function, there is no difference between d and e. You can apply various operations that are defined for delegates, such as ‘+=’, ‘-=’, ‘=’, ‘=null’, ‘==’, ‘( )’, etc.

    If you are outside this class, you can use any operation for d, but for e you can only execute ‘+=’ and ‘-=’. I.e. event introduces a limitation, even in derived classes.

    • Edited by Viorel_MVP Monday, March 16, 2020 8:38 PM
    • Marked as answer by Jeff0803 Sunday, March 22, 2020 12:12 AM
    Monday, March 16, 2020 8:17 PM