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 :-))
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.
Yes, method 2 is just shorthand for method 1 - at least in the case of using a method group. You can also use:
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:
instead of
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:
with
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.
It is sugar. The kind of sugar that really comes in handy when you have to write this:
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:
Even the above C# statement is sugar, the real code looks like this:
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.
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.
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?
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.