24

I am interested if it's possible using C# to write a code analogous to this Javascript one:

var v = (function()
{
    return "some value";
})()

The most I could achieve is:

Func<string> vf = () =>
{
    return "some value";
};

var v = vf();

But I wanted something like this:

// Gives error CS0149: Method name expected
var v = (() =>
{
    return "some value";
})();

Are there some way to call the function leaving it anonymous?

Alexander Prokofyev
  • 33,874
  • 33
  • 95
  • 118
  • 1
    Can you say what you want to do with the code exactly? What's the desired input and output? – Ahmad Farid Oct 13 '10 at 12:59
  • 5
    @Ahmad: The question is completely clear and unambiguous. – Timwi Oct 13 '10 at 13:02
  • Can you explain why you want to do this? Why go through all the rigamarole of defining an anonymous function and invoking it when you could simply place the body of the anonymous function *right there* and it would be invoked when the code runs? – Eric Lippert Oct 13 '10 at 14:20
  • @Eric Lippert: I use it this way inside <%= %> ASP.NET construction. – Alexander Prokofyev Oct 14 '10 at 04:14
  • @Alexander: Interesting. So what you are doing is essentially using a bunch of *statements* in a context where an *expression* is required. Isn't there some way you can run statements without having to jump through these hoops? – Eric Lippert Oct 14 '10 at 14:00
  • @Eric Lippert: I could use <% %> tags and Response.Write() at the end, but I would prefer the method discussed above by aesthetic reasons. :) – Alexander Prokofyev Oct 15 '10 at 05:02
  • See [why-cant-c-sharp-use-inline-anonymous-lambdas-or-delegates](http://stackoverflow.com/questions/2687942/why-cant-c-sharp-use-inline-anonymous-lambdas-or-delegates) – nawfal Jul 06 '14 at 13:02
  • @EricLippert I've used this technique to implement a "poor mans `let`" for C#. See [my answer below](https://stackoverflow.com/a/72591939/268581) for details. – dharmatech Jun 12 '22 at 12:02

3 Answers3

41

Yes, but C# is statically-typed, so you need to specify a delegate type.

For example, using the constructor syntax:

var v = new Func<string>(() =>
{
    return "some value";
})();

// shorter version
var v = new Func<string>(() => "some value")();

... or the cast syntax, which can get messy with too many parentheses :)

var v = ((Func<string>) (() =>
{
    return "some value";
}))();

// shorter version
var v = ((Func<string>)(() => "some value"))();
Timwi
  • 65,159
  • 33
  • 165
  • 230
  • Thank you very much! I should guess myself. – Alexander Prokofyev Oct 13 '10 at 13:03
  • I guess then it isn't possible with anonymous types or in Linq expressions? (Consider `() => new { "test" }` - can you call it literally?) – NetMage Apr 26 '17 at 19:55
  • @NetMage No, but you can declare a generic method that takes the lambda and simply returns it (`static Func Lambda(Func func) => func`) and then call it (`Lambda(() => new { Foo = "Test" })()`). Unfortunately you need a separate overload for every unique number of lambda parameters. – Timwi Apr 27 '17 at 07:13
  • This lets me invoke non-trivial code that I would only ever need to call once, and store it in a variable: `int width = new Func(() => { stmt; stmt; stmt; return something; }).Invoke();` – Craig Silver Jul 22 '18 at 19:53
  • @Timwi, See [my answer below](https://stackoverflow.com/a/72591939/268581) for something similar. A function called `Let`. – dharmatech Jun 12 '22 at 12:13
1

Let

With this helper function:

T Let<T>(Func<T> f) => f();

your example is then:

var v = Let(() => { return "abc"; });

Why the name Let?

It can be used similarly to let in other languages like Haskell, Scheme, and other Lisps.

This in Scheme:

(define c 
  (let ((a 10)
        (b 20))
    (+ a b)))

and this in Haskell:

c = 
  let 
    a = 10
    b = 20
  in a + b

can be written using Let in C#:

var c = Let(() => 
{
    var a = 10;
    var b = 20;

    return a + b;
});
dharmatech
  • 8,979
  • 8
  • 42
  • 88
0

Here's how you could then utilize such a construct to enclose context - closure-

Control.Click += new Func<string, EventHandler>((x) =>
new System.EventHandler(delegate(object sender, EventArgs e)
{

}))(valueForX);
  • 1
    This is doing way more than you need to. – Servy Mar 01 '13 at 20:12
  • 1
    Wasteful, redundant invocation of a function that doesn’t need to be a function. It sounds like you are coming from a JS background; this is necessary in JS only because variables are scoped to an entire function in JS. C# has proper correct scoping, so this is not necessary. – Timwi Apr 10 '14 at 13:32