Sign in to follow this  
Ntvu

I don't understand C# delegates and events

Recommended Posts

I've been learning about C# for about a month now and so far everything's going alright. I didn't find it too difficult to switch from PHP to C# besides a few adjustments I had to make. I'm able to comprehend most of C#'s features, except for two of them: delegates and events. I've read several articles and tutorials on them yet I feel that I don't understand them completely. I've tried using them before but I can't really think of a good time when I would need them. From what I know, a delegate in C# is basically a type-safe function pointer. You can initialize a delegate object with a method (?) and then you can call the delegate as if it were a method and it will call the function. I also read that in C# delegates are by reference and in C++ function pointers are by value, although I have no clue what this means. I'm not exactly sure how delegates would be of use. Why use a delegate instead of making a function accessible to another function/class in another scope? Why is it a good idea to pass delegates as arguments to functions? I know even less about events in C#. From what I read, they are based on a subscriber model where you can add a function to an event, something like this: myEvent += new Function And then once the event comes up then it will call the function and pass the arguments to it. Also I don't know what use I could make of events. What are some good situations to use them in and how do I use them properly? Can someone please explain this or point me to an article/tutorial that will provide me with a solid grasp on these features? Thanks.

Share this post


Link to post
Share on other sites
Ignore C++ function pointers if you don't know what they are. Concentrate on what a C# delegate is!

It's a reference to method. Or in .NET 2.0+, it's a list of method references. If you make a class that does something, oh say, a button, then you can create multiple instances of this button, and place them all over the screen with different text. But, what about when you click on it? You don't don't want every button to do the same thing do you? So you include a delegate in your button class that can hold a reference to a method(s).

You create your button, then say button.OnClick += MyButtonEventHandler4;

So simple! Events are icing for delegates. They allow you to treat delegates as properties and define a get/set for them (except for delegates its add/remove). This allows you do extra processing when you assign your method to the delegate.

HTH.

Oh, you don't necessarily *need* them either. But if you use any APIs like WinForms, they will use them, specifically for things like the button. They wrote reusable code for you but you don't have the source to that, so the only way you can customise it is by attaching your "on click" code to an instance of their button.

There, I feel I've sufficiently over described it!

Share this post


Link to post
Share on other sites
Quote:

I also read that in C# delegates are by reference and in C++ function pointers are by value, although I have no clue what this means.


It means just what it says. You understand the difference between reference types and value types?

Quote:

Why use a delegate instead of making a function accessible to another function/class in another scope?


Because delegates may be assigned at runtime. Thus if you don't know what function you need to call, a delegate serves this purpose. Why do you make:


public static int Add(int x, int y){ return(x+y); }


instead of

public static int Add1and1(){ return(1+1);}
public static int Add2and1(){ return(2+1);}
// and so on...


Variables allow the action to be abstracted. Variables abstract values, whereas delegates abstract behavior.

Quote:

I know even less about events in C#.


What operations can you do on delegates? Add, remove, set, invoke.

Let's look at one of the most direct uses for delegates: the button click. Delegates are used with buttons. What happens when you click a button? Depends on the button, right? It sucks to hard-code that behavior or inherit from button every time you want a button to do something new, so delegates are used.

But that sucks.

Code anywhere can re-set what the button does when it is clicked. Any code can just invoke the delegate, even if the button isn't clicked! So events were introduced for this sort of scenario. They're just delegates where the only public operations are Add and Remove. Code outside of the button can't re-set what the button does, and it can't make phantom button clicks. Only the button can do that.

And that's delegates/events in the nutshell!

Share this post


Link to post
Share on other sites
I don't quite get them 100% either. I think it's one of those things that you come to understand best by using them. The basic idea seems to be when you want a little more flexibility in choosing what function you use. If I understand it correctly...

Say you have a function... let's call it Narf(). The code in Narf() has a bunch of code at the beginning and end of it that is ran pretty much everytime. In the middle you'd probably have a line or two which can call various different functions. Now, you could give Narf an integer parameter and use that value in a case statement to figure out which of the different functions you want it to call. But, you'll have to modify Narf() everytime you want to expand that list. Alternatively, you can just tell Narf() what function you'll want that code in the middle to call if you use a delegate as a parameter for Narf(). Thus you skip the case statement and you don't need to maintain Narf().

But then again, I've never actually used delegates before and I'm still learning C# so you may want to take my explination with a grain of salt or two. I've been using the tutorials at C# Station

Share this post


Link to post
Share on other sites
Delegates also let you specify behavior via lambda expressions:


public delegate void Action<T>(T parameter);

public static void DoSomething<T>(IEnumerable<T> list, Action<T> action)
{
foreach(var item in list)
action(item);
}

DoSomething(Enumerable.Range(0, 10), i => Console.Write(i));



Will print out "0123456789" to the console.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this