Understanding delegates and Events in C# using a specific example

China☆狼群 提交于 2021-02-07 03:57:03

问题


So I'm at the point of understanding events and delegates.

I overally understand the usage of delegates. The only thing that concerns me about delegates is whether a delegate can be configured to work with functions that are not related to events in any way... if yes, how do I write the logic for a delegate-defined function? (I guess such function doesn't really have much of a point to it, but it's good to know.)

As for events... I'm having a hard time understanding it. I get the idea that an event is a function that gets executed when something happens in the code. However, I don't get the process of creating an event. Partially.

For this question I'll use an answer by Gary Willoughby: https://stackoverflow.com/a/803528/1104766 It was posted on a question from which I tried to understand this whole subject.

What I didn't get in the example above:
MyObject.OnMaximum += new MyEventHandler(MaximumReached);
First, how can you create an instance of a delegate, and pass it only 1 variable when it requires 2? There must be something I'm missing...
The second thing about this line is that the new ...() instance is being added to the OnMaximum function that resides in MyObject which is an instance of MyClass - what exactly is OnMaximum if such thing can be done? It was never really defined too!

      if(OnMaximum != null) {
        OnMaximum(this, new MyEventArgs("You've entered " +
          value.ToString() +
          ", but the maximum is " +
          Maximum.ToString()));
      }

As for this part, OnMaximum is called but it's logic was never really defined anywhere in the code, so what could be the outcome? Obviously I'd guess it'd be the text "You've entered............." but my question is to be more specific, what really happens with the values the function/event receives?

I marked all of my questions in BOLD for clarity.

P.S, I know this question generally has been posted a few times.
Please note that this specific question refers to an answer written by another member and the questions asked here are specific to this example. That's why such answers can't really be found in google.
For the record though, I did search before I posted, and I did try to understand, but I guess examples are the best way for me to understand something especially when my knowledge of the English CS vocabulary is lacking.


回答1:


I think you may be suffering from an overdose of syntactic sugar!

You see, all an event is, is a delegate. Actually, to be honest, it's a collection of delegates that can possibly be null.

Let's take an example:

public class Alarm
{
    public delegate void AlarmEvent();

    // my secret stuff

    // raise it!
    public void Ring()
    {
        if(OnAlert != null)
           OnAlert();
    }

    public event AlarmEvent OnAlert;
}

All the event keyword gives us here, is the ability to add and remove listeners to that event...

Alarm a = new Alarm();
a.OnAlert += myevent;
a.OnAlert += myotherevent;

A delegate on the other hand, whilst working exactly like we have just described, works more analogously as a function pointer. Imagine an abstract renderer, I could make the class as such:

public abstract class Renderer
{
    protected abstract void RenderImpl();
}

This means, I am bound to deriving from that render. But what if that renderer took a delegate?

public abstract class Renderer
{
    public delegate void RenderDelegate();

    public Renderer(RenderDelegate) { /* ... */ }
}

We are now separating out composition.

What am I getting at? Is either better or not? In the case of events, I am allowing the public to become observers of my class. They can react. In the second case, I define a user-supplied delegate to perform a niche function, whilst I retain the majority of control.

Delegates and events are mostly the same thing - but it is the design choices we make that ascertains which one is appropriate.

To address your other points, you bring up a great example of events versus delegates. If we were to change the alarm class above, to allow the delegate to return true or false, then what happens?

We'd get several observers returning true, but who is right and how to we check them?

Down the single delegate route, however... "Render successful" or "Render failed". Changing this single delegate is not so much of an issue. We can predictably test whether our renderer did the job:

if(!delegate_->Invoke())
    fallBackCode();

We can't really do that with events. Well, not predictably.

To put it more simply, events are there when you want to broadcast something and let someone else do something on receipt of that event. The bomb went off... Run, hide, call the National Guard, turn off the oven, or duck and cover.

Delegates allow you to change your functionality without changing your model (delegates follow a signature!). Great example of a delegate, is when you call List<T>.Sort. That's a delegate. It has a signature.

But you can also use them for more advanced things, such as altering a Renderer class without resorting to interfaces, and being able to supply a user-defined "snippet". I guess the easiest analogy here would be owner-drawn controls in Win32. No need to override the whole class, no need to provide an interface and write a lot of code. Just change the bit that renders the item in the combo box. Delegates are great examples of how you might achieve that.




回答2:


The tutorials at MSDN will answer all your questions:

Delegates: http://msdn.microsoft.com/en-us/library/aa288459(v=vs.71).aspx

Events: http://msdn.microsoft.com/en-us/library/aa645739(v=vs.71).aspx




回答3:


class Program
    {
        static void Main(string[] args)
        {
            Parent p = new Parent();
        }
    }

    ////////////////////////////////////////////

    public delegate void DelegateName(string data);

    class Child
    {
        public event DelegateName delegateName;

        public void call()
        {
            delegateName("Narottam");
        }
    }

    ///////////////////////////////////////////

    class Parent
    {
        public Parent()
        {
            Child c = new Child();
            c.delegateName += new DelegateName(print);
            //or like this
            //c.delegateName += print;
            c.call();
        }

        public void print(string name)
        {
            Console.WriteLine("yes we got the name : " + name);
        }
    }



回答4:


Come on Guys! All of you successfully complicated the DELEGATES :)!

I will try to leave a hint here : i understood delegates once I realized jquery ajax calls in Javascript. for ex: ajax.send(url, data, successcallback, failcallback) is the signature of the function. as you know, it sends data to the server URL, as a response, It might be 200OK or some other error. In case of any such event(success/fail), you want to execute a function. So, this acts like a placeholder of a function, to be able to mention in either success or failure. That placeholder may not be very generic - it might accept a set of parameters and may/may not return value. That declaration of such Placeholder, if done in C# IS CALLED DELEGATE! As javascript functions not strict with number of arguments, you would just see them as GENERIC placeholders...but C# has some STRICT declarations... that boils down to DELEGATE declarations!!

Hope it helps!



来源:https://stackoverflow.com/questions/14093325/understanding-delegates-and-events-in-c-sharp-using-a-specific-example

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!