Click here to Skip to main content
15,889,200 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Example will illustrate what I mean.

WinForms application with an 'OK' button and code to be executed when it's clicked.

Choice #1. Double-click the button in the IDE to create the stub within the form class.

Choice #2. Use an explicit lambda expression in the form constructor as follows:
C#
okButton.Click += (s, e) => okButton_Click();

I was leaning towards #2 on the grounds that it shows the connection explicitly without having to look through the events in the Properties window for that control.

Not a big deal either way, but am wondering if there's a consensus about which one is preferable.
Posted
Comments
Sergey Alexandrovich Kryukov 5-Feb-14 15:53pm    
I always prefer #2. Moreover, I never ever use #1, I think it is fundamentally wrong. I know too many problems with over-using the designer. It really should be used minimally, just to mark-up basic layout. By the way, did you notice that auto-generated code brutally violate Microsoft naming conventions? This is perfectly good, because 1) the generation cannot "know" your semantics, 2) it's good because you can easy spot (and exterminate) auto-generated code.

One benefit of lambda (but this is not the only way to define anonymous method, so this is the benefit of anonymous more than lambda), that you can ignore unused parameters:
something.Click += (sender, eventArgs) => { HandleClick(/* no meaningless parameters here */); };

Importantly, you control where you put this code. Auto-generated code should only do the simplest things.

—SA

First, I think it's great that you are diligently studying all the possible forms of creating EventHandlers, and "wiring them up" to various Control Events.

For simple uses of EventHandlers, I see lots of benefits from letting Visual Studio create stubs for the programmer via double-clicking on the Control, or selecting an Event in the Property Browser for a Control. This is a "convenience" functionality that increases your productivity, and encapsulates simple logical relations so you can focus on your "larger scale" tasks at hand.

There are no performance penalties for making use of this built-in functionality, and, if you are obsessive-compulsive, you may receive a bonus of something new to worry about, if the syntax bothers you :)

The "organic" reasons for creating your own EventHandlers in code (using Lambda expressions, anonymous methods) arise when you are doing more complex things. Obviously, if you define your own Events, you have to define your own EventHandlers to use those Events, but, let's consider some other cases in which you'd want to define your own EventHandlers:

1. When you want to directly manipulate the fact that a .NET Event is a multi-cast delegate that maintains a queue of possible EventHandlers all of which will be executed. By "manipulate" I mean remove an existing EventHandler, add an EventHandler, restore a previously removed EventHandler, etc.

2. as in #1, but with the stipulation that you want to directly manipulate the order in which EventHandlers in the Event's internal queue are executed.

3. in complex control situations where you might want to store EventHandlers. For example, imagine a Dictionary<TreeNode, CustomEvent> where you might want to execute different code based on a TreeNode. Or, imagine a "state machine" type of UI, where for each "state," you'd want to assign different EventHandlers to certain Controls that are present in the UI for each state.

An example of storing Delegates as Values in a Dictionary can be found in my article on DevX: [^]. You could store EventHandlers in exactly the same way.

Scenario #2 is one I am dealing with right now in a Project I am working on, and I have "solved" it by creating a static Property of Type Action in a static Class: under different circumstances different EventHandlers are assigned to that Property by various Forms, and the sequence of execution of the EventHandlers in response to a certain UI Event is re-structured. Sounds more exotic than it is.

This type of solution allows me to execute an EventHandler defined within various external objects (Forms) with no specific "tight coupling" between the static Class and the Forms, and, of course, since the EventHandler definition is "inside" a Form, it has access to all of the Form's private/public Fields, Methods, etc., while the static Class does not.
 
Share this answer
 
Actually, these aren't really two different choices. I agree with your concern, as one of the things I have always strongly disliked about certain languages and technologies (VB 6 being a great example of this, and VBA an even worse offender) is how much of this kind of hidden magic is involved in things.

But here you'll find that in neither case is there a magic, auto-subscription, though it may seem that way. When you create a form in Visual Studio, let's say "MainForm", if you look carefully, you'll note that the form class is spread out between two files, MainForm.cs and MainForm.Designer.cs, each of which starts with "partial class MainForm" meaning they both contribute code which is mashed together to compile into a single class. MainForm.cs typically contains all the stuff you add by hand (although you could create more files that contribute to the same class if you want for some reason). But the entire rest of the form-- the layout, the event subscriptions, everything-- is still done using regular old C# code, and you'll find it in MainForm.Designer.cs. The graphical editor in the IDE is just doing C# code generation, not hiding anything somewhere secret that you can't look at yourself.

So after you double-click on that button to auto-create an event handler, if you go look in the .Designer.cs file, in the method called InitializeComponent(), I think you'll see a line that looks very much like your "Choice #2," although it isn't probably using quite the same syntax (a lambda isn't actually necessary here).

I personally would think it preferable to put all this initialization in a single place most of the time, so basically I'd say just keep it consistent within an application. If you're going to use some tools other than Visual Studio for developing, and therefore create forms without using the VS graphical designer (you could do all of this in a text editor, for instance, without any graphical designer at all), or if you're going to be actively subscribing to and unsubscribing from events dynamically sometime after form initialization is complete, then you might have a good reason to put these somewhere else, but in many or most cases, I don't see why using the designer to insert these is a problem.
 
Share this answer
 
Comments
Member 10014315 5-Feb-14 14:11pm    
Many thanks for the detailed, well explained response.
Why on earth use a lambda anyway?
okButton.Click += (s, e) => okButton_Click();
I've never done that, when:
C#
okButton.Click += new EventHandler(okButton_Click);
will do the job...

But generally, I prefer to set them in the properties pane, I only explicitly add them in code if I also create the instance.


"The question arises, then, when WOULD one need to use lambda expressions? If the answer is long and/or complicated, then a link to something that might illuminate it for me would be much appreciated."

Primarily, in Linq methods and expressions, where you want to do something short and sweet:
C#
var found = myList.Where(c => c.Cost < 1000);

To do this without a lambda would make it a lot less readable, as you'd have to create a method just for this one line, and find a way to pass the "loop" values through.

Lambdas are for places where you are only going to use the method once, it's short and easily understood, and it makes the code more readable that the equivalent - which isn't difficult when you are used to them as having to trek half a file away to find a one line method:
C#
private bool IsCheap(MyClass c) { return c.Cost < 1000; }
Doesn't do much for readability! :laugh:
 
Share this answer
 
v3
Comments
Member 10014315 5-Feb-14 14:33pm    
Thanks for this. I'm kind of self-teaching myself C# and locked onto lambda expressions a little while back as the simpler way to connect events and methods. Without (explicitly at least) using delegates. The fog is lifting slowly for me, but I still don't fully understand quite a lot.
The question arises, then, when WOULD one need to use lambda expressions? If the answer is long and/or complicated, then a link to something that might illuminate it for me would be much appreciated.
OriginalGriff 5-Feb-14 14:52pm    
Answer updated

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900