I have a button event declared like this :
myButton.Click += new EventHandler(ButtonClicked);
private void ButtonClicked(Object s, EventArgs e)
{
this.Close();
}
I can do exactly the same like this :
myButton.Click += (s, e) => this.Close();
I'm sure the advantage of using the second way of doing it is not just aesthetic.
Why and when should I use the second method because now I'm confused? If it's just for the look of it, it doesn't look much cleaner when you have more than one instructions in the body of your anonymous function.
Technically there is no difference. Compiler will generate handler method in second case.
But frankly speaking I almost never use anonymous event handlers. Why? because they do not have names. IDE can't help me to find place where event is handled. Do you remember exact place where you subscribed with anonymous method? Well, you possibly remember that place. But I bet your teammates don't.
Also I don't like mixing styles of event handlers. Visual Studio generates for me button1_Click methods. I don't like having some handlers subscribed this way, and some subscribed in place.
And I like to see event argument type. And yes unsubscribing also matters sometime. And few more points - anonymous methods are useful for very simple logic (like closing form in your case), but them become very messy with something more complex. And I think that putting event handler in place breaks single responsibility of your method. It subscribes to event, does some other stuff, and handles event in same place. I like to separate things in order to make them more readable and maintainable.
The compiler generates a method for this anonymous function (s, e) => this.Close(); either way,
It's up to you where you want to use it, declaring it inside a method will however let you access variables declared in that method.
Well you have essentially implictly applied a delegate to your Click event.
You can't access this event in code anywhere else. The main advantage to this is that you can't call your method any where else in your class, by having a method you are inviting other "Team Members" to access the method in their code or potentially change the modifiers of it to what they think should happen.
Should you want to be able to override a method, then obviously inline anonymous assignments are a dis-advantage.
The usage is more or less dependant on how you want to handle access to the logic.
You can do it even more elegant if you do not need the arguments:
myButton.Click += delegate { this.Close(); };
but there is no profit besides elegant look behind it.
I prefer NOT to use lambda expressions ( => ) if I don't really need them as you can't change the scope code during debugging.
Anonymous Functions can be anonymous methods or lambda expressions. The lamba expression is of the form:
() => //dowork
Anonymous Methods are more verbose and support remains mainly for backwards compatibility. Anonymous Functions do not have a value or type in and of themselves, but it is convertible to a delegate or expression tree. Anonymous functions allow us to create in-line methods which are useful in cases such as setting up an event handler. This in-lining of methods allows developers to write code "in the same place". In other words, the handler is immediately available to the reader at the location where the event is handled.
I strive to in-line methods when the implementation is limited to a few statements and not re-useable (as is often the case in event handlers). Lamba Expressions can also used extensively in the framework's extensions methods Enumerable.Select, Where etc. And in place of Action or Func when using the new parallels library or calling Control.Invoke.
Here is a similiar subject: delegate keyword vs. lambda notation that considers anonymous delegates and lambda expressions. Particurarly, the answer there is: Once it is compiled, there is no difference between them.
The first method is easier to support, to make more complex and to reuse.
Also it is not obvious how to unsubscribe the second method from the event
As long as you don't need the parameters, you can even use:
myButton.Click += delegate { this.Close(); };
which looks even cleaner.
But by using anonymous delegates comes the cost of code reusability, as others have pointed out. Also in the article How to: Subscribe to and Unsubscribe from Events. Microsoft states that:
It is important to notice that you cannot easily unsubscribe from an
event if you used an anonymous function to subscribe to it. To
unsubscribe in this scenario, it is necessary to go back to the code
where you subscribe to the event, store the anonymous method in a
delegate variable, and then add the delegate to the event. In general,
we recommend that you do not use anonymous functions to subscribe to events if you will have to unsubscribe from the event at some later
point in your code.
One of the strong points of the anonymous methods, which also separates them from lambda expressions, is that:
... There is one case in which an anonymous method provides
functionality not found in lambda expressions. Anonymous methods
enable you to omit the parameter list. This means that an anonymous
method can be converted to delegates with a variety of signatures.
This is not possible with lambda expressions.
As a conclusion for the paragraph above we can say that you can either pass no parameters at all, or you should pass in the exact signature of the event handler:
myButton.Click += delegate(object sender, EventArgs e) { this.Close(); };
Related
This question already has answers here:
Is there a benefit to explicit use of "new EventHandler" declaration?
(4 answers)
Closed 9 years ago.
I am using c# Win Forms with Resharper and it gives me three options for event handler:
eg:
1.button.Click+= (sender, args) => ;
2.button.Click+= delegate(object sender, EventArgs args) { };
3.button3.Click+= Button3OnClick;
private void Button3OnClick(object sender, EventArgs eventArgs)
{
}
So my questions are:
What are the differences between using one over the others?
Is there a preferred way I should stick with?
Thanks
As everyone will tell you, they are equivalent.
One important thing to note though
from How to: Subscribe to and Unsubscribe from Events (C# Programming Guide)
It is important to notice that you cannot easily unsubscribe from an
event if you used an anonymous function to subscribe to it. To
unsubscribe in this scenario, it is necessary to go back to the code
where you subscribe to the event, store the anonymous method in a
delegate variable, and then add the delegate to the event. In general,
we recommend that you do not use anonymous functions to subscribe to
events if you will have to unsubscribe from the event at some later
point in your code.
3) button3.Click += Button3OnClick;
Here you attach delegate which referes to named method Button3OnClick.
2) button.Click += delegate(object sender, EventArgs args) { };
Here you declare anonymous method in .NET 1.1 style. And attach delegate which referes to this anonymous method. Compiler will generate ordinal named method for this anonymous method, so acutally that is same as
button.Click += CompilerGeneratedName;
Where
private void CompilerGeneratedName(object sender, EventArgs args)
{
}
On .NET version > 3 you unlikely will use this syntax, because it was simplified with lambdas.
1) button.Click += (sender, args) => ;
That is exactly same as previous case, but written in lambda syntax. Compiler will generate named method for this anonymous method.
All these options do same - they create and attach delegate which referers to method with required syntax. The only difference is the name of method - method gets name either before compilation, or during compilation.
Is there a preferred way I should stick with?
Usually lambdas (i.e. anonymous methods) are used for very small methods, which just don't worth creating named method manually. But event handlers often not that simple. So, I personally don't like having part of handlers named, and part of attached in-place, because I like to keep code in consistent way. I also like to see usages of event handler, have ability to unsubscribe handler from event, and handler name in stack. So I stick with named handlers. But you always should use same guidlines as your team does.
I would suggest reading up on events and delegates : Delegates and Events
But what it boils down to is that option 3 was always the defacto standard for creating events in .net 2. Since .net 3 delegates got introduced and made it easier to implement with the short hand, option 1 and option 2.
a delegate as used above specifies a place holder containing a signature and return type, the code inside the delegate describes the interactions.
If your learning about events , use option 3 to get your head around it. If you think you have the hang of delegates use option 2. And when it starts boring you to type out everything use option 1
:)
I am a beginner in C# events , and delegates. Few questions that would make sense if you look at the URL I have used to learn about events.
Can I ever have an event without a delegate associated to it? The exmaples that I have found always have them together.
For example I do not understand how does the event get generated. I am totally lost, I understand that Tick is defined as an event but what is the Tick's event description? where do I define what constitutes the Tick?
Also where does the Tick value gets ever initailized. It seems that all the examples I have looked at never initialize the event and have a similar statement to statement : If (Tick ! =null) in the attached example but it is not obviuos where is the Tick is initialized. I have looked around and I just cant find any answer.
Thanks in advance for your help
No, events are just a special use of delegates. You can't have an event without a delegate (though you can have a delegate without an event - read up on delegates for more info).
Not really sure I understand your question here. The description of the event would be in the documentation. Looking at the code alone, you just know that there is an event called Tick on that object that you can attach an event handler to.
When you add an event handler to Tick (that's the += lines you see) it will become non-null. That's what those != null checks are doing - making sure that someone has attached onto the event.
An event is simply a combination of an add method and a remove method, both of which take a single parameter of the same delegate type. What the event does with a passed-in delegate is entirely up to the implementation.
The most common thing to do with an event delegate received in the Add handler is to Delegate.Combine it with the previously-added delegates (if any), but there are some other possibilities as well:
If an object will support many kinds of events, but many instances will have zero subscribers for most of them, one could add the delegate to a table. Many WinForms events do this.
If one wants to allow subscribers to use contravariant delegate types, one could place received delegates into an array, List<>, linked list, of delegates or delegate-holding objects.
If the event represents something that some types of objects would fire, but a particular instance never will, the event may simply discard the delegate. Consider, for example, an abstract ObservableFoo class with an abstract change-notification event, and a contract that says any time the instance's properties change it will invoke all passed-in delegates will be invoked; an ImmutableFoo class derived from it could accept subscription requests, but since it would never change, it would never have to invoke the passed-in delegates (or do anything else with them) and could simply discard them.
Since an event is a pair of methods which take a delegate type as a parameter, every event must "by definition" use delegates as its parameter type. All non-trivial events must store passed-in delegates in some form. The most common way to accept multiple subscriptions is to combine them into a multicast delegate (I dislike the design, btw, but it is the most common); other approaches may be employed, but an event which is going to use passed-in delegates must store them somehow.
BTW, there are two ways to declare an event in C#: one may supply the add/remove handlers explicitly, in which case the compiler will create a event with those handlers. One may also supply just the event name and delegate type, in which case the compiler will create an event with the specified name and scope, a private variable with the same name and appropriate delegate type, and thread-safe add/remove methods which add or remove the event from the indicated variable. Statements of the form eventName += something; or eventName -= something; will be processed as calls to the "add" or "remove" methods; all other uses of the name will refer to the delegate. Note that in old versions of C#, use of eventName += something; and eventName -= something; within a class would be processed using the += and -= operations on the delegate which were not thread-safe, but newer versions have changed that behavior.
What's the difference between the two?
object.ProgressChanged += new EventHandler<ProgressChangedEventArgs>(object_ProgressChanged)
object.ProgressChanged += object_ProgressChanged;
void installableObject_InstallProgressChanged(object sender, ProgressChangedEventArgs e)
{
EventHandler<ProgressChangedEventArgs> progress = ProgressChanged;
if (installing != null)
installing(this, e);
}
EDIT:
If there are no difference, which is the better choice?
Thanks!
Basically, one is shorter than the other. It's just synctactic sugar.
The "correct" syntax is the first one, as ProgresChanged is an EventHandler event, so for you to assign a actual handler to it, you need to create a new EventHandler object, whose constructor takes as a parameter the name of a method with the required signature.
However, if you just specify the name of the method (second syntax), an instance of the eventHandler class is created implicitly, and that instance is assigned to the ProgressChanged event.
I prefer using the second method because it's shorter, and does not lose any information. There are not much contexts where you could mistake a += methodName construct for something else.
No difference. The same ilcode is generated.
As for which one is better: I use the second options since it's cleaner code = easier to read.
No difference. The second one will be implicitely converted to the first by the compiler.
There is no difference between the two, they are same.
In fact, the latter is just a shortcut and it will be compiled like the former.
Riana
Sometimes the simplest questions make me love C/C++ and C# more and more.
Today sitting on the bus musing aout delegates I remembered
reading somwhere you don't need to use the new keyword when instaniating
a new delegate.
For example:
public static void SomeMethod(string message)
{
...
}
...
public delegate void TestDelgate(string message); //Define a delegate
...........
//create a new instance ..METHOD 1
TestDelgate t = new TestDelgate(SomeMethod);
//OR another way to create a new instance ..METHOD 2
TestDelgate t = SomeMethod; //create a new instance ..METHOD 2
So todays questions are
What happens under the hood in method 2. Does the compiler expand method 2 into method 1, hence writing TestDelgate t = SomeMethod; is just a shortcut for
TestDelgate t = new TestDelgate(SomeMethod);, or is there another reason for the exsitence of method 2
Do you guys think method 1 or method 2 is better for readability (this is a subjective question, but I'd just like to get a unscientific feel of general opinion of stackoverflow :-))
Yes, method 2 is just shorthand for method 1 - at least in the case of using a method group. You can also use:
TestDelegate t = new TestDelegate(someExistingDelegate);
which allows for variance (not just the generic variance from C# 4) and creates a separate delegate... but that's rarely useful.
Personally I go with option 2... method group conversions are very handy like that. In particular it makes event wiring simpler:
button.Click += LoadDocument;
instead of
button.Click += new EventHander(LoadDocument);
The latter just has extra fluff - the former has better information density. It's also important when you're passing the delegate as a method argument. For example, compare:
observable.Subscribe(new Action<string>(Console.WriteLine));
with
observable.Subscribe(Console.WriteLine);
Unless there's any ambiguity in terms of which delegate type you actually want to convert the method group to, I just use the implicit conversion.
Under-the-hood, your 2 methods are exactly the same. It is just the compiler being smart about what you want to do. This little feature is called delegate inference and was added in C#2.0.
I think you should use #2, and take advantage of delegate inference. They compile to the same IL, and option #2 is shorter and more concise. It is easier to read and understand the meaning of the code, because there is less noise.
This syntax is also supported for events.
It is sugar. The kind of sugar that really comes in handy when you have to write this:
someObj.Test -= new TestDelegate(SomeMethod);
What? You have to use the new keyword to remove an event handler. Yes, you do. The VB.NET team really pained about this, they decided for a completely different syntax:
RemoveHandler someObj.Test, AddressOf SomeMethod
Even the above C# statement is sugar, the real code looks like this:
someObj.Test.remove(new TestDelegate(this, SomeMethod));
Where "remove" is the accessor function for an event. And "this" is required to initialize the Delegate.Target property. Now it is obvious that it is actually a method call and using the new keyword suddenly makes sense again. Hiding "this" has some disadvantages too, it isn't obvious anymore that an event subscription will prevent an object from getting garbage collected.
Yes they are compiled into the same thing.
I prefer #2. Just because it is shorter and not so clumsy. You already know that it is a TestDelegate due to defining that before. So why write it again?
It's just syntatic sugar for the explicit delegate creation. This was introduced in C# 2.0. You may have noticed that Visual Studio 2008 still generates the old-style (method 1) syntax if you ask it to create an event handler; I always replace it manually by the new syntax.
I normally prefer the shorter form in method 2. I used method 1 only once: with a delegate that was to be invoked from native code, and therefore could not be garbage-collected. I wanted to be very explicit about creating and assigning it.
Under the hood both statements create delegate object and pass to parameters to ctor: address of method and reference to this. second is just syntax sugar.
One advantage of the 'new' syntax is that it informed the programmer that a new object was being allocated; if it would be desirable to avoid repeatedly creating new identical delegates, one could pull the delegate out to a field. I know that in fact one is allowed to use one delegate to subscribe and another to unsubscribe, but to me that feels wrong. Storing to a field the delegate used to subscribe, and then unsubscribing using that same delegate feels cleaner. Cleaner still, IMHO, would have been if the act of subscribing would have returned a MethodInvoker which, when called, would unsubscribe (in which case an "event" would simply be a function that accepted an EventHandler and returned a MethodInvoker), but that's not how .net events work.
Can you tell me what the difference is between these methods of attaching an event handler?
//Method 1
this.button4.Click += new RoutedEventHandler(button4_Click);
//Method 2
this.button4.Click += button4_Click;
...
void button4_Click(object sender, RoutedEventArgs e) { }
As Anton says, there's no difference.
Just as a bit more background, this isn't specific to events. That's just one use of the feature in C# 2.0, which is implicit conversion of method groups to delegates. So you can similarly use it like this:
EventHandler handler = button4_click;
Another change to delegates in C# 2.0 is that they're now variant - this means that (for example) you can use a method declared with the EventHander signature as a MouseEventHandler:
MouseEventHandler handler = button4_click;
Then of course there's anonymous methods, but that's a whole different ballgame :)
No difference whatsoever - the second is just syntactic shugar added in C# 2.0. And in C# 3.0 lambdas are even more concise.
It is indeed syntactic sugar (it compiles to identical CIL)
The benefit to the first approach is that it is explict at the call site what event type you are using.
The benefit to the second is that, should the delegate type change but stay compatible the code will not require changing, if it changes but is incompatible you need only fix the method, not the places it is attached to the event.
As ever this is a balance as to which pro/con is more use to the situation at hand