In assigning event handlers to something like a context MenuItem, for instance, there are two acceptable syntaxes:
MenuItem item = new MenuItem("Open Image", btnOpenImage_Click);
...and...
MenuItem item = new MenuItem("Open Image", new EventHandler(btnOpenImage_Click));
I also note that the same appears to apply to this:
listView.ItemClick += listView_ItemClick;
...and...
listView.ItemClick += new ItemClickEventHandler(listView_ItemClick);
Is there any particular advantage for the second (explicit) over the first? Or is this more of a stylistic question?
In C# 1.0 you had no choice but to explicitly define the delegate type and the target.
Since C# 2.0 the compiler allows you to express yourself in a more succinct manner by means of an implicit conversion from a method group to a compatible delegate type. It's really just syntactic sugar.
Sometimes you have no choice but to use the long-winded syntax if the correct overload cannot be resolved from the method group due to an ambiguity.
It's syntax for older version of C# compiler (<=1.1). Not needed anymore. Current compilers are sophisticated enough to get it right.
There's one (little) benefit, sometimes. If you assign event handlers by "+=", the Intellisense autocomplete feature may make writing code a bit faster.
The only time when this is useful is if it would otherwise be ambiguous - for example, if it was MenuItem(string, Delegate) - of if there were multiple equally matching overloads that would match the signature. This also includes var syntax (shown below) and generic type inference (not shown):
EventHandler handler = SomeMethod; // fine
EventHandler handler = new EventHandler(SomeMethod); // fine
var handler = new EventHandler(SomeMethod); // fine
var handler = (EventHandler)SomeMethod; // fine
var handler = SomeMethod; // not fine
In all other cases, it is redundant and is unnecessary in any compiler from 2.0 onwards.
Related to your edit - The adding of handlers isn't really affected by using new or not but there's a slight difference in removing handlers like this
listView.ItemClick -= listView_ItemClick;
and
listView.ItemClick -= new ItemClickEventHandler(listView_ItemClick);
albeit unlikely to affect most scenarios. The first version, without the new keyword, is supposedly more efficient.
There's a detailed explanation in this post but the conclusion is
So both works but which one should we use? If the events are
subscribed/unsubscribed once at the beginning/end like in a typical
WinForm application then it hardly matters. However if this is done
multiple times then the second approach is preferable as it does less
of costly heap allocations and will work faster
(second approach in that post being the one without the new keyword)
Having said that it seems like a micro optimization to me so it's unlikely to be a bottleneck in the majority of cases.
Related
Edit:
I would be greatful if an experienced programmer with the ability to verify this sort of thing showed me the proof that this method is safe from memory leaks. I've been introducing it to many of my coding efforts but I still have a small doubt in my mind. Unfortunately I'm not good enough / don't know the tools to investigate it.
Original:
I learned recently that some uses of lambda expressions can create memory leaks:
ProjectData Project;
void OnLaunchNewProject()
{
NewProjectUI newProjectUI = new NewProjectUI();
newProjectUI.OnCompleted += (o, e) =>
{
Project = newProjectUI.NewProject;
view.Content = string.Format("Project {0} was created and saved successfully.", Project.Name);
};
newProjectUI.OnCancelled += (o, e) => { view.Content = "Operation was cancelled.";};
view.Content = newProjectUI;
}
I learned the bad impact of this method in this blog.
I do not fully understand the impact of referencing local variables in lambda expressions and this limits my ability to circumvent the problem.
Between the typical approach and the use of lambda, what's the ideal compromise? The thing I like about lambda is skipping the definition of the EventHandler's arguments in the body of my class (the sender/routed args) when I don't need them.
Unfortunately, the blog post you mentioned is wrong. There is not general issue with memory leaks in lambda expressions. In the blog examples, the finalizers are never called because the author never removes the anonymous methods from the event. So the .NET runtime thinks that the method still might be called later and cannot remove the class from memory.
In your code, you will release the NewProjectUI instance somewhere, and this is the point where all events become unsued and when the assigned lambda method also becomes unused. Then the GC can remove the anonymous lambda-helper-class and free the used memory.
So, again: There is no issue in .NET when using local variables in lambda expressions.
But to make your code better, move the code from the lambda expressions to named methods and add these methods to the events. This also makes it possible to remove the methods from the events when they're no longer needed.
What is the difference between:
this.btnConnect.Click += btnConnect_Click;
and:
this.btnConnect.Click += new RoutedEventHandler(btnConnect_Click);
It seems to work the same either way, but Visual Studio IntelliSense inserts the second example and I'm curious why.
My initial guess is that using the IntelliSense version makes it so that each button calls its own instance of the RoutedEventHandler, making it thread-safe?
And that using the first example, then each button would call the same instance of that method and they might step on each others feet.
It is the same thing, the first is just a syntactic sugar, i.e. compiler generates the same IL bytecode for both - there is always a delegate instance created.
IIRC, the first version of C# didn't allow the first syntax, it was introduced in C# 2.0.
You can also use Lambda to new a RoutedEventHandler:
new RoutedEventHandler(
(sendItem, args) =>
{
//things you want to do
IsTopMost = !IsTopMost;
this.Topmost = IsTopMost;
((MenuItem) sendItem).Header = menuWords[0, ++menuClickCount[0]%2];
})
When I deal set up events, I usually write as such:
data.event += new data.returndataeventhandler(method);
And have a method as such:
void method(parameter)
{
dosomething();
}
This is when the event returns an object.
I have just been reading through somebody elses code and they have used, what seems to be a much cleaner way, as such:
data.ReturnData += delegate(DataSet returnedDataSet)
{
dataset = returnedDataSet;
};
Is there any downfall to this way?
Thanks.
The one major downfall of using anonymous delegates (or the even-cleaner Lambda as suggested by tster) is that you're not going to be able to unsubscribe it from the event later unless you give it some sort of name.
In most cases, this is "No Big Deal (tm)" because the delegate will go away whenever the event source goes away, but this can be a "Subtle Mistake (tm)" if you're subscribing to static events or events on long-lived objects (e.g., the WPF Dispatcher object).
In your case, this doesn't look like a problem at all, so I'd definitely recommend going with tster's recommendation (assuming you're using an appropriately recent version of .Net):
data.ReturnData += returnedDataSet => dataset = returnedDataSet;
(The compiler can infer the type of returnedDataSet from the EventHandler type of ReturnData.)
The primary downfall of using anonymous delegates is that they are not reusable. Other than that there is typically no difference between defining a delegate and then using it elsewhere in your code versus using an anonymous delegate.
One down fall is that it will not appear in your method drop down list. If you do it inline, it should only be simple, nothing overly complex.
Like said by others, the most obvious is not reusable.
Other points:
readability in particular if you have large method body
because .NET generate a random name for anonymous method (not very meaningful or readable) if you use reflection type technology or profiler, it may complicate traceability.
The only downfall is that if you have more than one event it's easier to point it to a method. If you had to attach events in different blocks to the same handler, you would have to store your delegate somewhere so that both blocks could "see" it.
Even cleaner:
data.ReturnData += returnedDataSet => dataset = returnedDataSet;
Nope its just anonymous method thats all.
You can read more about anonymous methods here.
Aside from the other answers of reusablity/Intellisense, I believe the only downfall is if you need to remove the handler later. With a delegate/lamba you cannot easily remove your handler if it no longer needs to be called.
After discovering lambda expressions, and their use as anonymous functions, I've found myself writing a lot of more trivial events such as these:
txtLogin.GotFocus += (o, e) =>
{
txtLogin.Text = string.Empty;
txtLogin.ForeColor = SystemColors.ControlText;
};
txtLogin.LostFocus += (o, e) =>
{
txtLogin.Text = "Login...";
txtLogin.ForeColor = SystemColors.InactiveCaptionText;
};
I've also moved away from event handlers which just call other functions, replacing them with small lambdas which do the same:
backgroundWorker.DoWork += (o, e) => DatabaseLookup.Open(e.Argument as string);
I've found some similar questions addressing performance concerns and pointing out that you can't remove them, but I haven't found any addressing the simple question of is this a good idea?
Is the use of lambdas in such a way considered good form, or do more experience programmers look down on this? Does it hide event handlers in hard-to-find places, or does it do the code a service by reducing the number of trivial event handlers?
It's a perfectly reasonable idea - but in this particular case, I would use an anonymous method instead:
txtLogin.LostFocus += delegate
{
txtLogin.Text = "Login...";
txtLogin.ForeColor = SystemColors.InactiveCaptionText;
};
The benefit is that you don't have to specify the parameters - which makes it clearer that you're not using them. This is the only advantage that anonymous methods have over lambda expressions.
The performance hit is almost always going to be negligible. The inability to remove them afterwards is a very real problem if you do need to be able to remove the handler, but I find that often I don't. (Reactive Extensions has a nice approach to this - when you subscribe to an observable sequence, you're given back an IDisposable which will remove the subscription if you call it. Very neat.)
Actually, it's consider it putting event handlers in easy-to-find places, namely right next to the name of the event it's assigned to.
A lot of the time, you'll see event handlers like:
void Text1_KeyDown(....) {....}
attached to the KeyUp event of txtFirstName, because after using Intellisense to create the handler, someone decided to rename the textbox, and that KeyUp worked better. With the Lambda, the object, the event and the function are all together.
It's a tricky one. I remember reading in Code Complete about how some (smart) people say you should keep the flow of control as simple as possible, with many arguing for single entry and exit points from a method, because not doing so made the program harder to follow.
Lambdas are getting even further away from that, making it very difficult in some cases to follow what's happening, with control leaping around from place to place.
Basically, I think it probably is a bad idea because of this, but it's also powerful and makes life easier. I certainly use them a fair amount. In summary, use with caution!
This question already has answers here:
Where do I use delegates? [closed]
(8 answers)
Closed 9 years ago.
Duplicate:
Difference between events and delegates and its respective applications
What are the advantages of delegates?
Where do I use delegates?
I wonder what the purpose of delegates is. I haven't used them that much and can't really think of something.
In my courses, it's written that a delegate is a blue-print for all methods that comply with its signature.
Also, you can add multiple methods to one delegate, and then they'll be executed after eachother in the order they were added. Which is probably only usefull for methods that affect local variables or methodes that don't return any values.
I've read that C# implements Events as delegates, which is documented as being:
//Summary: Represents the method that
will handle an event that has no event
data.
//Parameters:
//sender: The source of the event.
//e: An System.EventArgs that contains no event data.
[Serializable]
[ComVisible(true)]
public delegate void EventHandler(object sender, EventArgs e);
Still, it's kinda confusing. Can someone give a good, usefull example of this concept?
Yeah,
You're almost there. A delegate refers to a method or function to be called. .NET uses the Events to say.. when someones presses this button, I want you to execute this piece of code.
For example, in the use of a GPS application:
public delegate void PositionReceivedEventHandler(double latitude, double longitude);
This says that the method must take two doubles as the inputs, and return void. When we come to defining an event:
public event PositionReceivedEventHandler PositionReceived;
This means that the PositionRecieved event, calls a method with the same definition as the
PositionReceivedEventHandler delegate we defined. So when you do
PositionRecieved += new PositionReceivedEventHandler(method_Name);
The method_Name must match the delegate, so that we know how to execute the method, what parameters it's expecting. If you use a Visual Studio designer to add some events to a button for example, it will all work on a delegate expecting an object and an EventArgs parameter.
Hope that helps some...
As you noted a delegate is a way to create a signature for an method call. There are many great examples of using delegates, but the one that really opened my mind is this example.
public delegate Duck GetDuckDelegate();
public GetDuckDelegate GiveMeTheDuckFactoryMethod(string type)
{
switch(type)
{
case "Rubber":
return new GetDuckDelegate(CreateRubberDuck);
case "Mallard":
return new GetDuckDelegate(CreateMallardDuck);
default:
return new GetDuckDelegate(CreateDefaultDuck);
}
}
public Duck CreateRubberDuck()
{
return new RubberDuck();
}
public Duck CreateMallardDuck()
{
return new MallardDuck();
}
public Duck CreateDefaultDuck()
{
return new Duck();
}
Then to use it
public static void Main() {
var getDuck = GiveMeTheDuckFactoryMethod("Rubber");
var duck = getDuck();
}
Arguably, the Factory pattern would be a better method for this, but I just thought up this example on the fly and thought it proved the point of how delegates can be treated as objects
Delegates allow you to pass methods around like values.
For example, .Net has a method called Array.ForEach that takes a delegate and an array, and calls the delegate on each element of the array.
Therefore, you could write,
int[] arr = new int[] { 1, 2, 4, 8, 16, 32, 64 };
Array.ForEach(arr, new Action<int>(Console.WriteLine));
This code will call Console.WriteLine for each number in the array.
There are many things you can do by making functions that take delegates, especially when combined with anonymous methods. For examples, look at LINQ.
Many people initially get confused with the real need for delegates and events. I was one of them and it took me some time to figure it out :-). Recently answered a similar query in ASP.NET forums and thought it would be good if I create a blog post on this topic! Here was the query:
"I was reading an example somewhere of a Bank Class that if the minimum balance is reached you need to inform the rest of the app that the min has reached, but can't we do that by just calling a normal method.
for example: lets say when we deduct some amount from the balance and if minimum reached then call some method to take some action, I am totally missing why do we need delegates and custom events here?"
Thing is in the Bank case, you can definitely call a method, but then it would be simple procedural programming, we need event based programming when we want our code to respond to some events generated by a system.
For eg.: think that windows OS is a system, and we are writing a code (in any language) where we want to capture an event like mouse_click(). Now how would our program know that a mouse click has occured? We can use low level code for it, but since OS is already handling low level code, its best to capture an event raised by the OS.
In other terms, the moment a mouse_click() happens the OS fires an event. The OS doesnt care who captures this event and uses it, it just sends out a notification. Then any code (like ours) can capture that event and use it accordingly. This saves us a lot of time to write code for the same ourselves. And other programs too can use the same event and handle it accordingly.
Similarly, the banking system can be huge, and many other outside applications might be accessing it. The banking system does not know how many such applications there are which need it, or are dependent on it, and how would they handle certain situations like when balance is low, so it simply fires an event whenever low balance occurs, and this event can be used by any other code, besides banking code itself.
Note that each susbcriber to that event can handle that event independently, for eg. the banking code might stop something from executing if balance is low, some other reporting app might send an email in such a case, or some ATM code can stop a particualr transaction and notify the user that balance is low.
Hope this clears things a bit!
I can provide you with an example using a web application architecture:
Generally, with a web application you can provide a front controller that receives requests from many clients. We could put all our methods within the front controller for dealing with the many different types of requests from the clients. However, this get a little cumbersome. Instead we can use delegates to encapsulate functionality for different requests. We could have:
Authentication Delegate
User Management Delegate
and so on. So it's a neat way to split up functionality into logical chunks - delegates. The Struts framework is based on this way of working (the ActionServlet and Action classes).
There are lots of excellent articles explaining delegates - here are some good ones:
Delegates and events
C# Delegates Explained
Delegates in C#
Delegates, to my understanding, provides a way of specializing the behavior of a class without subclassing it.
Some classes have complex generic behavior, but are still meant to be specialized. Think of a Window class in a GUI framework: A Window can propably do a lot on it's own, but you would most likely still want to specialize it in some way. In some frameworks, this is done via inheritance. A different way of doing it is with delegates. Say you want something to happen when the Window resizes: Your delegate class can then implement a method called onWindowResize (provided of course that the Window class supports this), which gets called whenever the Window resizes and is responsible for any specialized behavior when the Window resizes.
I'm not going to argue the merits of delegation over inheritance, but suffice it to say that there are many who feel that delegation is "cleaner" than inheritance.