I have a general question: in the C# code below thread tFour
can not be created and the compiler shows me the following error: "Anonymous function converted to a void returning delegate cannot return a value"
THE CODE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace DelegatesAndLambda
{
class Program
{
public static int ThrowNum(object a)
{
Console.WriteLine(a);
return 2 * (int)a;
}
static void Main(string[] args)
{
Func<int> newF = delegate () { int x = ThrowNum(2); return x; };
Thread tOne = new Thread( delegate () { int x = ThrowNum(2); });
Thread tTwo= new Thread(()=> ThrowNum(2));
Thread tThree = new Thread(() => newF());
Thread tFour = new Thread(delegate () { int x = ThrowNum(2); return x;});
}
}
}
However, threads tOne
, tTwo
and tThree
are created without an error. So why does the lambda expression allows to pass a method delegate with return (non-void) value and multiple parameters (ThrowNum(2), newF()
) while an anonymous method with return value ( delegate () { int x = ThrowNum(2); return x;}
) defined using the delegate keyword can not be passed? I thought in both cases we deal with anonymous methods? I do know that Thread
accepts only two types of signatures : void DoSomething()
and void DoSomething(object o)
but what is the major difference between initializations of tTwo
and tFour
using the same(?) anonymous method? I have been trying to find answer for a while but did not succeed.
Thanks
Also, we create anonymous functions in JavaScript, where we want to use functions as values. In other words, we can store the value returned by an anonymous function in a variable. In the above example, we stored the value returned by the function in the variable variableName.
Anonymous function converted to a void returning delegate cannot return a value.
Anonymous methods provide a technique to pass a code block as a delegate parameter. Anonymous methods are the methods without a name, just the body. You need not specify the return type in an anonymous method; it is inferred from the return statement inside the method body.
Just because an expression-bodied lambda expression has a result doesn't mean it's used. It's fine for a lambda expression that returns a result to be converted to a delegate with a void
return type, so long as its body is a valid statement expression. Here's a simple example:
using System;
class Test
{
static int Method() => 5;
static void Main()
{
Action action = () => Method();
}
}
That's fine, because Method()
is be a valid statement expression. It just calls the method, and ignores the result. This would not be valid, because 1 + 1
isn't a valid statement expression:
// error CS0201: Only assignment, call, increment, decrement,
// await, and new object expressions can be used as a statement
Action action = () => 1 + 2;
There's no such thing as an expression-bodied anonymous method, so thing become a bit simpler: you just can't return a value from an anonymous method and convert that anonymous method to a delegate type with a void
return type.
The relevant part of the C# 5 ECMA standard is 11.7.1:
Specifically, an anonymous function F is compatible with a delegate type D provided:
- ...
- If the body of F is an expression, and either D has a void return type or F is async and D has the return type Task, then when each parameter of F is given the type of the corresponding parameter in D, the body of F is a valid expression (w.r.t §12) that would be permitted as a statement-expression (§13.7).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With