100

This fails

string temp = () => {return "test";};

with the error

Cannot convert lambda expression to type 'string' because it is not a delegate type

What does the error mean and how can I resolve it?

leppie
  • 115,091
  • 17
  • 196
  • 297
4thSpace
  • 43,672
  • 97
  • 296
  • 475
  • 2
    Why is this question the first result in Google when searching for the error "anonymous function converted to a void returning delegate cannot return a value" when it's clearly have nothing to do with it? – Calmarius Jul 21 '18 at 15:12

6 Answers6

144

The problem here is that you've defined an anonymous method which returns a string but are trying to assign it directly to a string. It's an expression which when invoked produces a string it's not directly a string. It needs to be assigned to a compatible delegate type. In this case the easiest choice is Func<string>

Func<string> temp = () => {return "test";};

This can be done in one line by a bit of casting or using the delegate constructor to establish the type of the lambda followed by an invocation.

string temp = ((Func<string>)(() => { return "test"; }))();
string temp = new Func<string>(() => { return "test"; })();

Note: Both samples could be shorted to the expression form which lacks the { return ... }

Func<string> temp = () => "test";
string temp = ((Func<string>)(() => "test"))();
string temp = new Func<string>(() => "test")();
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • Thanks. So no way to do everything on one line (including assigning string)? The value I want ("test", which is actually a variable in real life) is inside another lambda so I loose scope if I try to define as you have above. – 4thSpace May 09 '12 at 17:20
  • @4thSpace it can be done in one line with some evil casting. I updated my answer to show the way – JaredPar May 09 '12 at 17:22
  • Or in this case, just `Func temp = () => "test";`. – Gabe May 09 '12 at 17:22
  • Or in the case of your edit, `string temp = new Func(() => "test")();` – Gabe May 09 '12 at 17:25
  • Perfect! If I wanted to pass in an int, can you show that in one line? I tried this but no go: ((Func)((4) => {return "test";}))(); – 4thSpace May 09 '12 at 17:40
  • @4thSpace you can't declare an int literal as a parameter, but you could use an identifier as a placeholder for the int parameter. `(x) => { return "test"; }` – JaredPar May 09 '12 at 17:42
  • Ok but I keep getting the error: Delegate 'Func' does not take 0 arguments. – 4thSpace May 09 '12 at 17:56
  • @4thSpace sorry, you also need to change tho type of the func to `Func` – JaredPar May 09 '12 at 18:11
  • Yep - you can see that above in my previous comment. Also tried "x" instead of 4. – 4thSpace May 09 '12 at 18:16
  • `Func temp = () => {"test";};` is even more succinct; the `return` keyword is only semantic candy. –  Dec 11 '15 at 09:21
  • @user152949 - if you read the whole answer, at the bottom is the even shorter way to represent without `return`: `Func temp = () => "test";` – ToolmakerSteve Apr 11 '17 at 01:57
  • ... in fact, with the `{ ... }` but no `return`, it gives a compiler error *"not all code paths return a value ..*". The `return` is not semantic candy - it is necessary syntax *if you are inside a block* - otherwise, the compiler does not know what value the block is returning. It is the block syntax `{ ... return ..; }` that is "semantic candy", if you can represent your logic as an expression. – ToolmakerSteve Apr 11 '17 at 02:23
  • I was trying to inline an anonymous method 'y' into a .base(x,y) constructor call. The logic was right, but I needed the incantation to turn it into a delegate type. This answer nailed it - dark magic indeed. – Eight-Bit Guru Jul 06 '20 at 15:27
20

You are attempting to assign a function delegate to a string type. Try this:

Func<string> temp = () => {return "test";};

You can now execute the function thusly:

string s = temp();

The "s" variable will now have the value "test".

Dave Swersky
  • 34,502
  • 9
  • 78
  • 118
8

Using a little helper function and generics you can let the compiler infer the type, and shorten it a little bit:

public static TOut FuncInvoke<TOut>(Func<TOut> func)
{
    return func();
}

var temp = FuncInvoke(()=>"test");

Side note: this is also nice as you then are able to return an anonymous type:

var temp = FuncInvoke(()=>new {foo=1,bar=2});
joeriks
  • 3,382
  • 8
  • 32
  • 42
  • 1
    Interesting technique. Does this add run-time overhead, or is it all at compile time? – ToolmakerSteve Apr 11 '17 at 01:52
  • @ToolmakerSteve: My guess is that it would add a teeeeensy bit of runtime overhead (it's wrapping a call to an anonymous method inside another method) - however, I suspect it would also depend on where the FuncInvoke method was defined (same assembly as where it's being called vs different assembly etc), since it *might* be the sort of thing that the compiler could "inline". This is the kind of question that people answer by writing a quick test program, compiling, and then picking apart the resulting IL. – Daniel Scott May 18 '19 at 06:50
  • @ToolmakerSteve Following on from that last "guess" at performance impact, I would add that even the worst-case impact this would have on performance would be virtually nil (one extra function call, to a non-virtual, static method). Anyone using this technique is likely doing so because they're throwing lambdas around. That means they're probably using at least a couple of LINQ extension methods somewhere, so the odds are fair to good that they've inadvertently chained a couple of LINQ methods together in a way that hurts performance 100,000 times worse than one extra function call ;) – Daniel Scott May 18 '19 at 06:59
7

you can use anonymous method with argument :

int arg = 5;

string temp = ((Func<int, string>)((a) => { return a == 5 ? "correct" : "not correct"; }))(arg);
HamidReza
  • 1,726
  • 20
  • 15
4

An anonymous method can return a value using a func delegate. Here is an example where I have shown how to return a value using an anonymous method.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {


        static void Main(string[] args)
        {
            Func<int, int> del = delegate (int x)
              {
                  return x * x;

              };

            int p= del(4);
            Console.WriteLine(p);
            Console.ReadLine();
        }
    }
}
dipdapdop
  • 126
  • 1
  • 10
Debendra Dash
  • 5,334
  • 46
  • 38
0

This is another example using C# 8 (could also work with other .NET versions supporting parallel tasks)

using System;
using System.Threading.Tasks;

namespace Exercise_1_Creating_and_Sharing_Tasks
{
    internal static class Program
    {
        private static int TextLength(object o)
        {
            Console.WriteLine($"Task with id {Task.CurrentId} processing object {o}");
            return o.ToString().Length;
        }

        private static void Main()
        {
            const string text1 = "Welcome";
            const string text2 = "Hello";

            var task1 = new Task<int>(() => TextLength(text1));
            task1.Start();

            var task2 = Task.Factory.StartNew(TextLength, text2);

            Console.WriteLine($"Length of '{text1}' is {task1.Result}");
            Console.WriteLine($"Length of '{text2}' is {task2.Result}");

            Console.WriteLine("Main program done");
            Console.ReadKey();
        }
    }
}
wbadry
  • 797
  • 16
  • 27