3

I would like to create a lambda expression and invoke it immediately and I would like to avoid creating a delegate; a trivial example1:

int i = (() => 42)();

This produces the error:

CS0149 Method name expected

There are two workarounds:

  • Declare a (local) method:

    int Return42() => 42;
    
    int i = Return42();
    
  • Create a delegate:

    int i = ((Func<int>)(() => 42))();
    

It is possible to create and immediately invoke a lambda expression without creating a delegate and without naming it? And if possible, how can one create such a lambda?


1. In reality it is an async Task that I would like to use instead of Task.ContinueWith (I tried to follow what Stephen Cleary said: you should strive to replace ContinueWith with await); e.g:

Task<int> future = (async () =>
                       (await RetrieveLookupFromFarAway())["42"].First())();

With RetrieveLookupFromFarAway something like:

async Task<ILookup<string, int>> RetrieveLookupFromFarAway()
{
    await Task.Delay(1000);
    return Enumerable.Empty<int>().ToLookup((x) => x.ToString());
}

Kasper van den Berg
  • 8,951
  • 4
  • 48
  • 70

1 Answers1

4

The concept of a lambda expression only exists as source code. It doesn't even have a type in itself (just like the null literal doesn't have a type). It has to be converted to either an expression tree or a delegate: that's what exists as far as the IL and the CLR are concerned. The compiler has to emit code to create something, and you need to tell it which type you want that to be.

The compiler doesn't play favourites in terms of delegate types: while it could "know" about Func<T> and use that as a default delegate type for a lambda expression with no parameters, it doesn't.

The closest you'll get to what you want is to have a convenience method that you can call accepting a Func<T>, which could either just return the function, or execute it and return the result. For example:

public static Func<T> CreateFunc<T>(Func<T> func) => func;
public static T ExecuteFunc<T>(Func<T> func) => func();

Then you can call it as:

CreateFunc(() => 42)();

or

ExecuteFunc(() => 42);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194