0

I wrote the following code:

int n1 = 5
Task<int> myTask = new Task<int>(n1 => lib.MultiplyNumberTimes2(n1));
myTask.Wait();
Console.WriteLine("Result is " + myTask.Result.ToString());

Code explanation on what I want it to do:

I was expecting this to create a new task called myTask, which would accept a n1 int variable, and with it, it would run the lib.MultipleNumerTimes2 method. Then after waiting for it to complete, I would print the task result on screen with a myTask.Result statement.

But Visual studio shows an error on line 2 of my above code, underlining the n1 before the goto operator (=>) saying:

A local variable named 'n1' cannot be declared in this context, because it would give a different meaning to 'n1' which is already used in a 'parent or current' scope to denote something else

I'm guessing this a mistake in my lambda expression sintax which I can't yet understand. Aren't lambda expressions declared like: parameters => expression ? I know I'm declaring an anonymous expression, which I wan't to give an int variable, and then through the => operator use that same variable to run a function, but Visual Studio thinks I'm trying to declare a new n1 variable when in reality I just want to use it as a parameter. Also, while messing with the code I noticed changing line 2 for this fixes it:

Task<int> myTask = new Task<int>(() => lib.MultiplyNumerTimes2(n1));

I know I can leave it like that, but I would like to know what's wrong with my lambda expression that it won't let me send it any aprameters

sgarcia.dev
  • 5,671
  • 14
  • 46
  • 80

1 Answers1

2

The compilation error says exactly what you're doing wrong - you're trying to use the name n1 for two different things. You've got a local variable here:

int n1 = 5;

... and then you're also trying to use it your lambda expression parameter name. You need to use a different parameter name... or just use your current approach which captures n1 and doesn't have any parameters.

Note that there aren't any overloads of the Task<TResult> constructor which accept an Func<T, TResult>, so even just changing the name won't work:

new Task<int>(foo => lib.MultiplyNumerTimes2(foo));

But this would, as it calls the method accepting a Func<Object, TResult> and then provides the relevant value for the parameter.

new Task<int>(foo => lib.MultiplyNumerTimes2((int) foo), n1);

Note the cast, as the type of foo will just be object.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I understand the error, but wasn't that how lambda expressions work? I thought lambda expressions were just like writing anonymous methods where: method (int myInt) { myInt*2 } turned into: myInt => myInt*2 I didn't want to declare a new variable, am I not allowed to send parameters just like I would in a method? I mean, I wanted to send the n1 as a parameter, and altough I could also use that quickfix I found, I thought the correct thing was to send parameters correctly. I don't get how I'm supposed to send a parameter if it asks me to change it's name. – sgarcia.dev Jul 24 '14 at 21:21
  • @sgarcia: Yes, that's how lambda expressions work - but you can't use the same name for a lambda parameter as a local variable. They're two different things. The thing about a lambda expression (just like an anonymous method) is that it can *use* the local variable. I don't think you understand what the lambda expression parameter means - it's a variable which *receives* a value (just like in a regular method). It's not the name of an *existing* local variable that you're passing in as an *argument*. The local variables are captured already, which is how the parameterless approach works. – Jon Skeet Jul 24 '14 at 21:24
  • I think i'm not yet ready for lambda expressions serious usage from the looks of it, I'll go study more, thank you. – sgarcia.dev Jul 24 '14 at 21:29
  • @sgarcia: I suspect reading a good book carefully would be a good idea, yes. Good luck! – Jon Skeet Jul 24 '14 at 21:34