tags:

views:

45

answers:

2

The following code compiles and runs fine.

void myInvokedMethod(string s)
{
    Console.WriteLine(s);
}

void myInvoker()
{
    Invoke(new MethodInvoker(delegate() { myInvokedMethod("one"); }));
    Invoke(new MethodInvoker(delegate   { myInvokedMethod("two"); }));
}

When I call myInvoker, both calls to myInvokedMethod get through. What do the parentheses after delegate mean, and why do they appear to be optional?

+3  A: 

They specify the formal parameters the anonymous method takes, and they're optional if it takes none. If it is declared without a parameter list, it can be assigned to a delegate type that does take parameters.

Matthew Flaschen
+3  A: 

The parentheses is called the anonymous method parameter list, and is empty in this case. The anonymous method doesn't have a type - the compiler tries to perform an implicit conversion. If the signature of the anonymous method is given it must match the signature of the delegate.

Implicit conversion is also possible if the following all hold:

  • The formal parameter list of the delegate is omitted
  • The delegate has no out parameters
  • The return types match

This is the case in your second example. So there is no difference between those two lines - both do the same thing. Here is another example:

var x1 = new ParameterizedThreadStart(delegate(object o) {}); // Compiles.
var x2 = new ParameterizedThreadStart(delegate {});           // Compiles.
var x3 = new ParameterizedThreadStart(delegate() {});         // Does not compile.

The last two examples show that delegate(){} and delegate{} are not equivalent in general. They are only equivalent in your case because MethodInvoker takes no parameters. See the C# specification section 21 for more details and more examples.

Mark Byers