Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I define an Action in line in a method expecting a delegate?

Given the following MSDN sample code, why can't I define the Action delegate "inline":

public static void Main(string[] args)
{
    Action someAction = () => Console.WriteLine("Hello from the thread pool!");

    Task.Factory.StartNew(someAction);
}

...so "inline" like:

public static void Main(string[] args)
{
    Task.Factory.StartNew(Action someAction = () => Console.WriteLine("etc."));
}

Thanks,

Scott

like image 454
Scott Davies Avatar asked Jul 05 '10 13:07

Scott Davies


3 Answers

This isn't valid C#:

public static void Main(string[] args)
{
    Task.Factory.StartNew(Action someAction = () => Console.WriteLine("etc."));
}

Do this instead:

public static void Main(string[] args)
{
    Task.Factory.StartNew(() => Console.WriteLine("etc."));
}
like image 157
Tim Robinson Avatar answered Nov 13 '22 17:11

Tim Robinson


You're trying to delegate a variable within a method call. Just removing the variable declaration may be fine:

public static void Main(string[] args)
{
    Task.Factory.StartNew(() => Console.WriteLine("etc."));
}

Here the Action is inferred not from the lambda expression itself, but from the method call it's trying to make. Normal overload resolution is performed, and the compiler tries to convert the lambda expression to the relevant parameter type. If the parameter type were just Delegate (e.g. Control.Invoke) then type inference would fail because the compiler wouldn't have any concrete target types to try to convert to.

If that doesn't work (I can't easily test it atm) then you just need a cast to tell it which delegate type the lambda expression should be converted to:

public static void Main(string[] args)
{
    Task.Factory.StartNew((Action)(() => Console.WriteLine("etc.")));
}

To be honest though, at that point I'd prefer to see a separate variable in terms of readability.

like image 40
Jon Skeet Avatar answered Nov 13 '22 18:11

Jon Skeet


You are including the declaration statement, which is not a legal expression. Try:

Task.Factory.StartNew(() => Console.WriteLine("etc."));

If you call an API where the type of the delegate can't be inferred, you can use a cast or call the delegate constructor explicitly:

Task.Factory.StartNew((Action)(() => Console.WriteLine("etc.")));
Task.Factory.StartNew(new Action(() => Console.WriteLine("etc.")));
like image 2
Quartermeister Avatar answered Nov 13 '22 18:11

Quartermeister