tags:

views:

45

answers:

3

I'm just looking at some of my code and it occurred to me that given,

      Action<int> fireMessage = FireMessages;
      fireMessage.BeginInvoke(1, r => fireMessage.EndInvoke(r), null);

As I can directly assign a method to a delegate, why can't I just call BeginInvoke on the method directly. The way this code reads suggests that the delegate assignment is redundant.

But calling BeginInvoke directly on the method throws up a compiler exception.

+1  A: 

A method isn't a delegate - a delegate is distinct type which references a method - there is actually more information in a delegate than just the method.

Techically, it might be possible for the compiler to wire this up for you and shorten the typing, but I'm actually somewhat thankful that this wasn't done. By forcing you to assign a delegate to a method reference on an object, then invoke the delegate using BeginInvoke, the compiler is forcing you to be more explicit in your desire here.

Calling a delegate via BeginInvoke potentially has some serious side effects - this should be an explicit, purposeful action. Many methods will not behave as expected if they're called in separate threads, and at least this way, you need to know what you're doing in order to work in this manner.

That being said, in .NET 4, I'd recommend changing how you "fire methods" in "background threads". Instead of using Delegate.BeginInvoke, I'd recommend considering changing to using the new Task class:

Task.Factory.StartNew( () => FireMessages(1) );

There are many advantages to the new task library, especially when it comes to error handling, cancellation, prevention of oversubscription on the thread pool, etc.

Reed Copsey
A: 

I think it is by design. In C# methods are not objects like they are in functional languages, but delegates are.

Delegate constructor is "point of touching" that is supported by C# compiler, and this is single place where method is used as 'method reference' instead of 'method invokation'.

Accessing 'instance's method instance' object using someInstance.Method.SomeMethodOfMethod have confusing syntax, and requires method instance. Some person may expect method instances obtained from the same method of the same object must be also same, and this will requires additional memory usage to store method instance inside object.

STO
+1  A: 

There is a bit of syntactic sugar here. A delegate is really under the hood an object that wraps your method, and it happens to have the BeginInvoke method defined. The syntactic sugar is that you can assign a "method" to a delegate (without explicitly creating a delegate), but it only works in this context.

Grzenio