0

Please consider the following:

private static string Sub(int anInt)
{
    return anInt.ToString();
}

private static void Test()
{
    const int anInt = 100;

    Func<int,string> aFunc = Sub;

    //why does Task<string> task = Task.Run(aFunc(anInt)); not compile?
    Task<string> task = Task.Run(() => aFunc(anInt));

    Console.WriteLine(task.Result);
}

This code compiles fine. Why does the line

Task<string> task = Task.Run(aFunc(anInt));

not compile?

Is there a way to pass in a delegate invocation without a Lambda expression?

What am I missing?

3 Answers3

0

The error states

cannot convert from 'string' to 'System.Action'

By passing aFunc(anInt) you're basically passing the result of the method invocation - a string. Think of it this way - if you're typing () after the name of the Func variable - you're executing it on the spot.

If you want to pass a Func with its parameters, you have to do it the exact same way you said it compiles for you:

Task<string> task = Task.Run(() => aFunc(anInt));

... because this wraps your invocation in a new executable, which is then run.

Check this answer for more details.

Community
  • 1
  • 1
nikovn
  • 1,900
  • 5
  • 22
  • 28
0

Let's analyse this line:

Task<string> task = Task.Run(aFunc(anInt));

This line does not compile because the compiler understands aFunc(anInt) as "Execute aFunc(anInt), then use its return value as the parameter when calling Task.Run()".

Essentially, you are trying to force a string into Task.Run. It is equivalent to trying this:

Task<string> task = Task.Run("blah");

The above line will produce the exact same error message.

Serge
  • 3,986
  • 2
  • 17
  • 37
0

You can't do that because you are invoking aFunc instead of referring to it.

If you start passing parameters to a method, instead of simply giving its name, you're invoking it.

To refer to a method, only give the name and do not pass any parameters. Just like what you did here:

Func<int,string> aFunc = Sub;

You don't pass any parameters to Sub because you're just saying "What I mean is that method called Sub".

Now let's look at the erroneous code:

Task<string> task = Task.Run(aFunc(anInt));

Task.Run takes a parameter of type Action but you're giving it the return value of aFunc, which is a string. See why it's producing the error now?

You just can't say "What I mean is this method, called with an argument of anInt". It's simply impossible. You have to create a lambda for this.

Sweeper
  • 213,210
  • 22
  • 193
  • 313